如何使用 stringgrid 单元格的值存储在应该保存当前游戏状态的数组中?

How can I use the value of a stringgrid cell to be stored in an array which should hold the current game state?

我是编程新手,我正在尝试使用 3x3 数组制作 delphi tictactoe 游戏,以帮助我学习基础知识。

我正在使用一个 stringgrid,我想显示板的状态,用户在单元格上放置一个 X(通过鼠标单击)。我希望在代码的这一部分使用 stringgrid.cell(ARow,ACol) 作为位置将 'X' 添加到游戏板数组。我现在了解到这不能工作,因为数组是 char 类型。有解决办法吗?

我知道这不是制作游戏的最佳方式,但它可以帮助我学习。任何帮助将不胜感激。这是我的代码:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ButtonGroup,
  Vcl.Grids;

type
  TForm1 = class(TForm)
    Button1: TButton;
    label1: TLabel;
    StringGrid1: TStringGrid;
    Button2: TButton;

    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure Button2Click(Sender: TObject);
    procedure FormShow(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
    procedure restart();
    procedure compTurn();
  end;

var
  Form1: TForm1;
  gameBoard: array [1 .. 3, 1 .. 3] of char; // array for the game board.
  iScore: Integer;
  bTurn: Boolean = True; // O's go = false, X's go = true.

implementation

{$R *.dfm}
{ TForm1 }

procedure TForm1.Button2Click(Sender: TObject);
begin

  restart;
end;

procedure TForm1.compTurn;
begin
  // if (bTurn = false) then
  label1.Caption := 'Computer`s turn';

end;

procedure TForm1.FormShow(Sender: TObject);
begin
  restart;
end;

procedure TForm1.restart;
var
  i, j: Integer;
begin
  // place ? in the cells
  StringGrid1.Enabled := True;

  for i := 1 to 3 do
    for j := 1 to 3 do
      StringGrid1.cells[i, j] := '?';
  label1.Caption := 'Player X`s turn';
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
Var
  sX: string;
  pos: Integer;
begin

  sX := 'X';
  CanSelect := false;

  // Place a X or O in the cell depending on whose turn it is
  if (bTurn = True) then
    StringGrid1.cells[ACol, ARow] := sX // and gameBoard[ACol, ARow]

  else

    bTurn := false; // computer's turn to move
  compTurn; // make sure user can't add an X
  StringGrid1.Enabled := false;

end;

end.```

I was hoping at this part in the code it would add the 'X' to the gameboard array using the stringgrid.cell(ARow,ACol) for the position. I've now learnt that this cannot work as the array is a char type. Is there a way around this?

您在这里面临的问题是,在您的 StringGrid1SelectCell 事件处理程序中,您将 sX 变量定义为字符串。因此,如果您尝试将 sX 的值分配给您的 char 数组,Delphi 将不允许您这样做,因为您无法将整个字符串存储到一个 char 中。

要实现所需的功能,您应该将 sX 变量改为 Char 类型。这将允许您将其值写入数组。

现在您可能认为这会导致问题,因为您还需要将 sX 变量的值分配给特定的字符串网格单元格,因为字符串网格单元格是字符串类型。你不会的。

您始终可以将单个字符分配给字符串。这会将字符串的长度更改为 1,并且它将仅包含您提供的特定字符。

简而言之:

  • 将 String 分配给 Char 不起作用
  • 将 Char 分配给字符串确实有效

PS 另外不要忘记,如果您需要在满足 if 子句条件时执行多个命令,则需要将这些命令包含在 begin..end 块中。

因此您的代码应该如下所示(尚未测试)

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
Var
  sX: Char; //Change type from String to Char
  pos: Integer;
begin

  sX := 'X';
  CanSelect := false;

  // Place a X or O in the cell depending on whose turn it is
  if (bTurn = True) then
  //Enclose multiple commands with begin..end block
  begin
    StringGrid1.cells[ACol, ARow] := sX // and gameBoard[ACol, ARow]
    GameBoard[ACol,ARow] := sX;
  else
    bTurn := false; // computer's turn to move
  compTurn; // make sure user can't add an X
  StringGrid1.Enabled := false;

end;