首页 > 解决方案 > 如何使用 stringgrid 单元格的值存储在应该保存当前游戏状态的数组中?

问题描述

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

我正在使用一个字符串网格,我想显示板的状态,用户在单元格上放置一个 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.```

标签: arraysdelphi

解决方案


我希望在代码中的这一部分,它将使用 stringgrid.cell(ARow,ACol) 作为位置将“X”添加到游戏板数组中。我现在知道这不能工作,因为数组是 char 类型。有没有解决的办法?

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

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

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

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

简而言之:

  • 将字符串分配给 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;

推荐阅读