⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameboard.pas

📁 描述了根据五子规则做出相应的分步预测和胜负判断!也对DELPHI的面向对象的程序开发系统做了相应的阐述!
💻 PAS
📖 第 1 页 / 共 4 页
字号:
unit GameBoard;

interface

uses
  Dialogs, ComCtrls;

const
  BoardWidth = 15;
  BoardHeight = 15;

  //  边的类型的个数:11
  EdgeTypeNum = 11;

  MaxScore = 900000;

type
  TChessType = (Edge, None, Black, White);
  TBoard = array[0..BoardWidth + 1, 0..BoardHeight + 1] of TChessType;

  TDirection = (Left, UpperLeft, Up, UpperRight);

  TEnum = (eNo, eDead2, eLive2LooseEdge, eLive2Loose, eLive2Packed, eDead3, eLive3LooseEdge, eLive3Loose, eLive3Packed, eDead4, eLive4, eFive);

const
  No = shortint(eNo);
  Dead2 = shortint(eDead2);
  Live2Loose = shortint(eLive2Loose);
  Live2LooseEdge = shortint(eLive2LooseEdge);
  Live2Packed = shortint(eLive2Packed);
  Dead3 = shortint(eDead3);
  Live3LooseEdge = shortint(eLive3LooseEdge);
  Live3Loose = shortint(eLive3Loose);
  Live3Packed = shortint(eLive3Packed);
  Dead4 = shortint(eDead4);
  Live4 = shortint(eLive4);
  Five = shortint(eFive);

type // Dead4和 Live4Loose 合并为 Dead4
  // ( No, Dead1, Live1, Dead2, Live2Loose, Live2Packed, Dead3, Live3Loose, Live3Packed, Dead4, Live4, Five);
  // 为负代表端点
  TEdgeEnum = -Five..Five;

  TEdgeImage = array[1..5] of TEdgeEnum;
  TEdgeModel = record
    EdgeImage: byte;
    Edgetypes: TEdgeImage;
  end;

  TEdgeEnumPos = record
    Edge: TEdgeEnum;
  end;
  TEdgeType = record
    case integer of
      0: (int: integer);
      1: (TypeNum: array[Left..UpperRight] of TEdgeEnumPos);
  end;
  TEdgeTypeBoard = array[1..BoardWidth, 1..BoardHeight] of TEdgeType;

  {  TPoint = record
      Score: real;
      Score1: real;
      case integer of
        0: (int: integer);
        1: (dx, dy: smallInt);
    end;
   }
  TEdgeBoard = array[Black..White] of TEdgeTypeBoard;

  TGameBoard = class
  private
    Board: TBoard;

    {一共有10种 '边’:
       活1,死1,两种活2,死2,两种活3,死3,两种活4
    }
    EdgeBoard: TEdgeBoard;

  public
    constructor Create;
    destructor Destroy; override;
    procedure Reset;
    function GetXY(x, y: integer): TChessType; //  得到棋盘x, y处的值
    function GetTypeString(TypeOfChess: TChessType): string;
    function WinPlace(x, y: integer; TypeOfChess: TChessType; var Score: real): boolean;
    function GetType(TypeChess: TChessType; x, y: integer; dir: TDirection; var Pos: integer): TEdgeEnum;
    function GetEdgeImage(image: byte; Nurmber: integer; Closed: boolean): TEdgeImage;
    procedure UpdateDir(dir: TDirection; x, y: integer);
    procedure UpdateEdgeBoard(x, y: integer);
    function SetXY(x, y: integer; TypeOfChess: TChessType): boolean; //  设置棋盘x, y处的值
    procedure GetNextStep(TypeOfChess: TChessType; var x, y: integer);
    procedure GetNextStepWithDepth(TypeOfChess: TChessType; var x, y: integer; depth: integer); //  递归产生下一步
  end;

const
  ModelLimit: array[0..4] of integer = (0, 5, 10, 10, 5);

  Live2Model: array[1..5] of TEdgeModel = (
    (EdgeImage: $10 {10000}; EdgeTypes: (Live2Packed, Live2Packed, Live2Loose, Live2LooseEdge, Live2LooseEdge)),
    (EdgeImage: $08 {01000}; EdgeTypes: (Live2Packed, Live2Packed, Live2Packed, Live2Loose, Live2LooseEdge)),
    (EdgeImage: $04 {00100}; EdgeTypes: (Live2Loose, Live2Packed, Live2Packed, Live2Packed, Live2Loose)),
    (EdgeImage: $02 {00010}; EdgeTypes: (Live2LooseEdge, Live2Loose, Live2Packed, Live2Packed, Live2Packed)),
    (EdgeImage: $01 {00001}; EdgeTypes: (Live2LooseEdge, Live2LooseEdge, Live2Loose, Live2Packed, Live2Packed))
    );

  Live3Model: array[1..10] of TEdgeModel = (
    (EdgeImage: $0C {01100}; EdgeTypes: (Live3Packed, Live3Packed, Live3Packed, Live3Packed, Live3Loose)),
    (EdgeImage: $0A {01010}; EdgeTypes: (Live3Loose, Live3Packed, Live3Packed, Live3Packed, Live3Loose)),
    (EdgeImage: $18 {11000}; EdgeTypes: (Live3Packed, Live3Packed, Live3Packed, Live3Loose, Live3LooseEdge)),
    (EdgeImage: $14 {10100}; EdgeTypes: (Live3Packed, Live3Packed, Live3Packed, Live3Loose, Live3LooseEdge)),
    (EdgeImage: $12 {10010}; EdgeTypes: (Live3Loose, Live3Loose, Live3Loose, Live3Loose, Live3LooseEdge)),
    (EdgeImage: $11 {10001}; EdgeTypes: (Live3LooseEdge, Live3LooseEdge, Live3LooseEdge, Live3LooseEdge, Live3LooseEdge)),

    (EdgeImage: $06 {00110}; EdgeTypes: (Live3Loose, Live3Packed, Live3Packed, Live3Packed, Live3Packed)),
    (EdgeImage: $03 {00011}; EdgeTypes: (Live3LooseEdge, Live3Loose, Live3Packed, Live3Packed, Live3Packed)),
    (EdgeImage: $05 {00101}; EdgeTypes: (Live3LooseEdge, Live3Loose, Live3Packed, Live3Packed, Live3Packed)),
    (EdgeImage: $09 {01001}; EdgeTypes: (Live3LooseEdge, Live3Loose, Live3Loose, Live3Loose, Live3Loose))
    );

  Live4Model: array[1..10] of TEdgeModel = (
    (EdgeImage: $0E {01110}; EdgeTypes: (Live4, Live4, Live4, Live4, Live4)),
    (EdgeImage: $16 {10110}; EdgeTypes: (Live4, Live4, Live4, Live4, Dead4)),
    (EdgeImage: $15 {10101}; EdgeTypes: (Dead4, Dead4, Dead4, Dead4, Dead4)),
    (EdgeImage: $1A {11010}; EdgeTypes: (Live4, Live4, Live4, Live4, Dead4)),
    (EdgeImage: $19 {11001}; EdgeTypes: (Dead4, Dead4, Dead4, Dead4, Dead4)),
    (EdgeImage: $1C {11100}; EdgeTypes: (Live4, Live4, Live4, Live4, Dead4)),

    (EdgeImage: $0D {01101}; EdgeTypes: (Dead4, Live4, Live4, Live4, Live4)),
    (EdgeImage: $0B {01011}; EdgeTypes: (Dead4, Live4, Live4, Live4, Live4)),
    (EdgeImage: $13 {10011}; EdgeTypes: (Dead4, Dead4, Dead4, Dead4, Dead4)),
    (EdgeImage: $07 {00111}; EdgeTypes: (Dead4, Live4, Live4, Live4, Live4))
    );
  Live5Model: array[1..5] of TEdgeModel = (
    (EdgeImage: $0F {01111}; EdgeTypes: (Five, Five, Five, Five, Five)),
    (EdgeImage: $17 {10111}; EdgeTypes: (Five, Five, Five, Five, Five)),
    (EdgeImage: $1B {11011}; EdgeTypes: (Five, Five, Five, Five, Five)),
    (EdgeImage: $1D {11101}; EdgeTypes: (Five, Five, Five, Five, Five)),
    (EdgeImage: $1E {11110}; EdgeTypes: (Five, Five, Five, Five, Five))
    );

var

  //  ConstScore :      array [ No .. Five ] of real = (0, 2, 40, 90, 95, 30, 120, 175, 185, 190, 1000, 9000);//(0, 1, 40, 90, 95, 50, 220, 275, 300, 320, 1000, 9000);
  ConstScore: array[No..Five] of real = (0, 1, 5, 8, 10, 6, 170, 255, 285, 290, 3000, 8000);
  Win: boolean = False;

implementation

uses MainForm, SysUtils;


function InBound(x, Min, Max: integer): boolean;
begin
  Result := (x >= Min) and (x <= Max);
end;

function ReverseType(TypeOfChess: TChessType): TChessType;
begin
  Result := Black;
  if TypeOfChess = Black then
    Result := White;
  if ((TypeOfChess = None) or (TypeOfChess = Edge)) then
    Showmessage(' Type Error! ');
end;
{
function GetLevel(theType : TEdgeEnum): integer;
begin
Result := 1;
if theType >= Live2Loose then
  Result := 2;
if theType >= Live3Loose then
  Result := 3;
if theType >= Dead4 then
  Result := 4;
if theType = Five then
  Result := 5;
end;
}

procedure GetDirDelta(Dir: TDirection; var deltaX, deltaY: integer);
begin
  case Dir of
    Left: begin
        deltaX := 1;
        deltaY := 0;
      end;
    UpperLeft: begin
        deltaX := 1;
        deltaY := 1;
      end;
    Up: begin
        deltaX := 0;
        deltaY := 1;
      end;
    UpperRight: begin
        deltaX := -1;
        deltaY := 1;
      end;
  end; //  case
end;

constructor TGameBoard.Create;
begin
  inherited Create;
  Reset;
end;

destructor TGameBoard.Destroy;
begin

  inherited Destroy;
end;

//  重置棋盘

procedure TGameBoard.Reset;
var i, j: integer;
begin
  for i := 0 to BoardWidth + 1 do
    for j := 0 to BoardHeight + 1 do
      Board[i, j] := Edge;
  for i := 1 to BoardWidth do
    for j := 1 to BoardHeight do
      Board[i, j] := None;

  for i := 1 to BoardWidth do
    for j := 1 to BoardHeight do
    begin
      EdgeBoard[Black][i, j].int := 0;
      EdgeBoard[White][i, j].int := 0;
    end;
end;

function TGameBoard.GetTypeString(TypeOfChess: TChessType): string;
begin
  if TypeOfChess = Black then
    Result := 'Black'
  else
    Result := 'White';
end;

//  得到棋盘x, y处的值

function TGameBoard.GetXY(x, y: integer): TChessType;
begin
  Result := None;
  if (inbound(x, 1, BoardWidth) and inBound(y, 1, BoardHeight)) then
    Result := Board[x, y];
end;

function TGameBoard.GetType(TypeChess: TChessType; x, y: integer; dir: TDirection; var Pos: integer): TEdgeEnum;
begin
  Result := EdgeBoard[TypeChess][x, y].TypeNum[dir].Edge;
end;

function TGameBoard.GetEdgeImage(image: byte; Nurmber: integer; Closed: boolean): TEdgeImage;
var NextType: TEdgeEnum;
  i: integer;
  Mach: boolean;

begin
  Mach := False;
  if Closed then
  begin
    NextType := No;
    case Nurmber of
      1: NextType := Dead2;
      2: NextType := Dead3;
      3: NextType := Dead4;
      4: NextType := Five;
    end; // case
    for i := 1 to 5 do
      Result[i] := NextType;
    exit;
  end;

  case Nurmber of
    1:
      begin
        for i := 1 to ModelLimit[1] do
        begin
          if Live2Model[i].EdgeImage = image then
          begin
            Result := Live2Model[i].Edgetypes;
            Mach := True;
            break;
          end;
        end;
      end;
    2:
      begin
        for i := 1 to ModelLimit[2] do
          if Live3Model[i].EdgeImage = image then
          begin
            Result := Live3Model[i].Edgetypes;
            Mach := True;
            break;
          end;
      end;
    3:
      begin
        for i := 1 to ModelLimit[3] do
          if Live4Model[i].EdgeImage = image then
          begin
            Result := Live4Model[i].Edgetypes;
            Mach := True;
            break;
          end;
      end;
    4:
      begin
        Mach := True;
        for i := 1 to 5 do
        begin
          Result[i] := Five;
        end;
      end;
  end; // case

  if not Mach then
    Form1.StatusBar1.Panels[4].Text := 'Mach error!' + inttostr(integer(Nurmber));
end;

procedure TGameBoard.UpdateDir(dir: TDirection; x, y: integer);

const TypeArrayMax = 9;

var dirx, diry: integer;
  i, j: integer;
  image: byte;
  Sum: integer;
  NoNeed: boolean;
  ChessType, OtherType: TChessType;
  ResultImage: TEdgeImage;
  TypeImage: array[-TypeArrayMax..TypeArrayMax] of TChessType;
begin
  GetDirDelta(dir, dirx, diry);
  for i := -TypeArrayMax to TypeArrayMax do
    TypeImage[i] := Edge;
  for i := 0 to TypeArrayMax do
    if Board[x + i * dirx, y + i * diry] <> Edge then
      TypeImage[i] := Board[x + i * dirx, y + i * diry]
    else
      break;
  for i := -1 downto -TypeArrayMax do
    if Board[x + i * dirx, y + i * diry] <> Edge then
      TypeImage[i] := Board[x + i * dirx, y + i * diry]
    else
      break;

  // Elimate Older
  for ChessType := Black to White do
  begin
    for i := 0 to 5 do
      if TypeImage[i] = Edge then
        break
      else
      begin
        EdgeBoard[ChessType][x + i * dirx, y + i * diry].TypeNum[dir].Edge := No;
      end;
    for i := -1 downto -5 do
      if TypeImage[i] = Edge then
        break
      else
      begin
        EdgeBoard[ChessType][x + i * dirx, y + i * diry].TypeNum[dir].Edge := No;
      end;
  end;

  //  Try to Update
  for i := -8 to 4 do
  begin
    if (TypeImage[i] = Edge) then continue;

    for ChessType := Black to White do
    begin
      Sum := 0;
      image := 0;
      NoNeed := False;
      OtherType := ReverseType(ChessType);
      for j := i to i + 4 do
      begin
        if TypeImage[j] = ChessType then
        begin
          inc(Sum);
          image := image or (1 shl (4 - (j - i)));
        end else
          if ((TypeImage[j] = OtherType) or (TypeImage[j] = Edge)) then
          begin
            NoNeed := True;
            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -