Changeset 104 for trunk/Game.pas
- Timestamp:
- Dec 9, 2024, 3:42:36 PM (13 days ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Game.pas
r102 r104 5 5 uses 6 6 Classes, SysUtils, Dialogs, Generics.Collections, Graphics, Types, Forms, Math, DateUtils, 7 Controls, RegistryEx ;7 Controls, RegistryEx, Tile, Board, History; 8 8 9 9 type 10 10 TGame = class; 11 TMoveDirection = (drNone, drLeft, drUp, drRight, drDown);12 TTileAction = (taNone, taMove, taMerge, taAppear);13 11 TColorPalette = (cpOrangeYellow, cpGreenYellow, cpPinkBlue, cpBlueCyan, 14 12 cpGreenCyan, cpPinkRed); 15 16 { TTile }17 18 TTile = class19 Index: TPoint;20 Value: Integer;21 NewValue: Integer;22 Merged: Boolean;23 Action: TTileAction;24 Shift: TPoint;25 procedure Assign(Source: TTile);26 end;27 28 TTiles = class(TObjectList<TTile>)29 end;30 13 31 14 { TArea } … … 36 19 class function Create(P1, P2: TPoint): TArea; static; overload; 37 20 class function Create(X1, Y1, X2, Y2: Integer): TArea; static; overload; 38 end;39 40 { THistoryMove }41 42 THistoryMove = class43 Direction: TMoveDirection;44 NewItemPos: TPoint;45 NewItemValue: Integer;46 procedure SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);47 procedure LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);48 end;49 50 { THistoryMoves }51 52 THistoryMoves = class(TObjectList<THistoryMove>)53 procedure SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);54 procedure LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);55 end;56 57 TTilePosValue = record58 Pos: TPoint;59 Value: Integer;60 end;61 62 { THistory }63 64 THistory = class65 Game: TGame;66 Moves: THistoryMoves;67 InitialTiles: array of TTilePosValue;68 procedure GetStep(GameStep: TGame; Step: Integer);69 procedure Clear;70 constructor Create;71 destructor Destroy; override;72 procedure SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);73 procedure LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);74 end;75 76 { TBoard }77 78 TBoard = class79 private80 FSize: TPoint;81 procedure SetSize(AValue: TPoint);82 public83 Tiles: array of array of TTile;84 procedure Assign(Source: TBoard);85 procedure Clear;86 procedure ClearMerged;87 function GetValueSum: Integer;88 function GetHighestTileValue: Integer;89 function GetEmptyTilesCount: Integer;90 procedure GetEmptyTiles(EmptyTiles: TTiles);91 procedure SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);92 procedure LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);93 destructor Destroy; override;94 property Size: TPoint read FSize write SetSize;95 21 end; 96 22 … … 141 67 BackgroundColor: TColor; 142 68 Value2Chance: Double; 69 procedure Replay(History: THistory; Step: Integer); 143 70 function CanUndo: Boolean; 144 71 procedure Undo; … … 227 154 end; 228 155 229 { THistoryMoves }230 231 procedure THistoryMoves.SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);232 var233 I: Integer;234 begin235 with Reg do begin236 CurrentContext := RegContext;237 WriteInteger('Count', Count);238 for I := 0 to Count - 1 do begin239 Items[I].SaveToRegistry(Reg, TRegistryContext.Create(RegContext.RootKey, RegContext.Key + '\' + IntToStr(I)));240 end;241 end;242 end;243 244 procedure THistoryMoves.LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);245 var246 I: Integer;247 begin248 with Reg do begin249 CurrentContext := RegContext;250 Count := ReadIntegerWithDefault('Count', 0);251 for I := 0 to Count - 1 do begin252 Items[I] := THistoryMove.Create;253 THistoryMove(Items[I]).LoadFromRegistry(Reg, TRegistryContext.Create(RegContext.RootKey, RegContext.Key + '\' + IntToStr(I)));254 end;255 end;256 end;257 258 { THistoryMove }259 260 procedure THistoryMove.SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);261 begin262 with Reg do begin263 CurrentContext := RegContext;264 WriteInteger('Direction', Integer(Direction));265 WriteInteger('NewItemPosX', NewItemPos.X);266 WriteInteger('NewItemPosY', NewItemPos.Y);267 WriteInteger('NewItemValue', NewItemValue);268 end;269 end;270 271 procedure THistoryMove.LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);272 begin273 with Reg do begin274 CurrentContext := RegContext;275 Direction := TMoveDirection(ReadIntegerWithDefault('Direction', Integer(drNone)));276 NewItemPos := Point(ReadIntegerWithDefault('NewItemPosX', 0),277 ReadIntegerWithDefault('NewItemPosY', 0));278 NewItemValue := ReadIntegerWithDefault('NewItemValue', 0);279 end;280 end;281 282 { THistory }283 284 procedure THistory.GetStep(GameStep: TGame; Step: Integer);285 var286 I: Integer;287 begin288 GameStep.Board.Size := Game.Board.Size;289 GameStep.Board.Clear;290 GameStep.Skin := Game.Skin;291 GameStep.ColorPalette := Game.ColorPalette;292 GameStep.Score := 0;293 for I := 0 to Length(InitialTiles) - 1 do294 GameStep.Board.Tiles[InitialTiles[I].Pos.Y, InitialTiles[I].Pos.X].Value := InitialTiles[I].Value;295 for I := 0 to Step - 1 do296 with Moves[I] do begin297 GameStep.MoveAll(Direction, False);298 if GameStep.Board.Tiles[NewItemPos.Y, NewItemPos.X].Value = 0 then299 GameStep.Board.Tiles[NewItemPos.Y, NewItemPos.X].Value := NewItemValue300 else raise Exception.Create(STileShouldBeEmpty);301 end;302 end;303 304 procedure THistory.Clear;305 begin306 Moves.Clear;307 SetLength(InitialTiles, 0);308 end;309 310 constructor THistory.Create;311 begin312 Moves := THistoryMoves.Create;313 end;314 315 destructor THistory.Destroy;316 begin317 FreeAndNil(Moves);318 inherited;319 end;320 321 procedure THistory.SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);322 var323 I: Integer;324 begin325 with Reg do begin326 CurrentContext := TRegistryContext.Create(RegContext.RootKey, RegContext.Key + '\InitialTilesPos');327 WriteInteger('Count', Length(InitialTiles));328 for I := 0 to Length(InitialTiles) - 1 do begin329 WriteInteger('X' + IntToStr(I), InitialTiles[I].Pos.X);330 WriteInteger('Y' + IntToStr(I), InitialTiles[I].Pos.Y);331 WriteInteger('Value' + IntToStr(I), InitialTiles[I].Value);332 end;333 Moves.SaveToRegistry(Reg, RegContext);334 end;335 end;336 337 procedure THistory.LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);338 var339 I: Integer;340 begin341 with Reg do begin342 CurrentContext := TRegistryContext.Create(RegContext.RootKey, RegContext.Key + '\InitialTilesPos');343 SetLength(InitialTiles, ReadIntegerWithDefault('Count', 0));344 for I := 0 to Length(InitialTiles) - 1 do begin345 InitialTiles[I].Pos := Point(ReadIntegerWithDefault('X' + IntToStr(I), 0),346 ReadIntegerWithDefault('Y' + IntToStr(I), 0));347 InitialTiles[I].Value := ReadIntegerWithDefault('Value' + IntToStr(I), 0);348 end;349 end;350 Moves.LoadFromRegistry(Reg, RegContext);351 end;352 353 156 { TArea } 354 157 … … 370 173 Result.P1 := Point(X1, Y1); 371 174 Result.P2 := Point(X2, Y2); 372 end;373 374 { TBoard }375 376 procedure TBoard.SetSize(AValue: TPoint);377 var378 X, Y: Integer;379 begin380 if FSize = AValue then Exit;381 for Y := 0 to FSize.Y - 1 do382 for X := 0 to FSize.X - 1 do383 Tiles[Y, X].Free;384 FSize := AValue;385 SetLength(Tiles, FSize.Y, FSize.X);386 for Y := 0 to FSize.Y - 1 do387 for X := 0 to FSize.X - 1 do begin388 Tiles[Y, X] := TTile.Create;389 Tiles[Y, X].Index := Point(X, Y);390 end;391 end;392 393 procedure TBoard.Assign(Source: TBoard);394 var395 X, Y: Integer;396 begin397 Size := Source.Size;398 for Y := 0 to Size.Y - 1 do399 for X := 0 to Size.X - 1 do400 Tiles[Y, X].Assign(Source.Tiles[Y, X]);401 end;402 403 procedure TBoard.GetEmptyTiles(EmptyTiles: TTiles);404 var405 X, Y: Integer;406 begin407 EmptyTiles.Clear;408 for Y := 0 to Size.Y - 1 do409 for X := 0 to Size.X - 1 do410 if Tiles[Y, X].Value = 0 then411 EmptyTiles.Add(Tiles[Y, X]);412 end;413 414 procedure TBoard.SaveToRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);415 var416 X, Y: Integer;417 Value: string;418 begin419 with Reg do begin420 CurrentContext := RegContext;421 422 WriteInteger('SizeX', Size.X);423 WriteInteger('SizeY', Size.Y);424 Value := '';425 for Y := 0 to Size.Y - 1 do begin426 for X := 0 to Size.X - 1 do begin427 Value := Value + IntToStr(Tiles[Y, X].Value);428 if X < Size.X - 1 then Value := Value + ',';429 end;430 if Y < Size.Y - 1 then Value := Value + ';'431 end;432 WriteString('TileValues', Value);433 end;434 end;435 436 procedure TBoard.LoadFromRegistry(Reg: TRegistryEx; RegContext: TRegistryContext);437 var438 X, Y: Integer;439 Items: TStringList;440 Lines: TStringList;441 Number: Integer;442 begin443 with Reg do begin444 CurrentContext := RegContext;445 446 Size := Point(ReadIntegerWithDefault('SizeX', 4), ReadIntegerWithDefault('SizeY', 4));447 Items := TStringList.Create;448 Items.Delimiter := ',';449 Lines := TStringList.Create;450 Lines.Delimiter := ';';451 Lines.DelimitedText := ReadStringWithDefault('TileValues', '');452 for Y := 0 to Lines.Count - 1 do begin453 Items.DelimitedText := Lines[Y];454 for X := 0 to Items.Count - 1 do begin455 if TryStrToInt(Items[X], Number) and (X < Size.X) and (Y < Size.Y) then456 Tiles[Y, X].Value := Number;457 end;458 end;459 Lines.Free;460 Items.Free;461 end;462 end;463 464 destructor TBoard.Destroy;465 begin466 Size := Point(0, 0);467 inherited;468 end;469 470 procedure TBoard.ClearMerged;471 var472 X, Y: Integer;473 begin474 for Y := 0 to Size.Y - 1 do475 for X := 0 to Size.X - 1 do476 Tiles[Y, X].Merged := False;477 end;478 479 function TBoard.GetValueSum: Integer;480 var481 X, Y: Integer;482 begin483 Result := 0;484 for Y := 0 to Size.Y - 1 do485 for X := 0 to Size.X - 1 do486 Inc(Result, Tiles[Y, X].Value);487 end;488 489 function TBoard.GetEmptyTilesCount: Integer;490 var491 X, Y: Integer;492 begin493 Result := 0;494 for Y := 0 to Size.Y - 1 do495 for X := 0 to Size.X - 1 do496 if Tiles[Y, X].Value = 0 then497 Inc(Result);498 end;499 500 function TBoard.GetHighestTileValue: Integer;501 var502 X, Y: Integer;503 begin504 Result := 0;505 for Y := 0 to Size.Y - 1 do506 for X := 0 to Size.X - 1 do507 if Result < Tiles[Y, X].Value then Result := Tiles[Y, X].Value;508 end;509 510 procedure TBoard.Clear;511 var512 X, Y: Integer;513 begin514 for Y := 0 to Size.Y - 1 do515 for X := 0 to Size.X - 1 do516 Tiles[Y, X].Value := 0;517 end;518 519 520 { TTile }521 522 procedure TTile.Assign(Source: TTile);523 begin524 Value := Source.Value;525 Merged := Source.Merged;526 175 end; 527 176 … … 610 259 Skin := Source.Skin; 611 260 ColorPalette := Source.ColorPalette; 261 RecordHistory := Source.RecordHistory; 262 //History.Assign(Source.History); 612 263 end; 613 264 … … 1142 793 end; 1143 794 795 procedure TGame.Replay(History: THistory; Step: Integer); 796 var 797 I: Integer; 798 begin 799 Board.Clear; 800 Score := 0; 801 for I := 0 to Length(History.InitialTiles) - 1 do 802 Board.Tiles[History.InitialTiles[I].Pos.Y, History.InitialTiles[I].Pos.X].Value := History.InitialTiles[I].Value; 803 for I := 0 to Step - 1 do 804 with History.Moves[I] do begin 805 MoveAll(Direction, False); 806 if Board.Tiles[NewItemPos.Y, NewItemPos.X].Value = 0 then 807 Board.Tiles[NewItemPos.Y, NewItemPos.X].Value := NewItemValue 808 else raise Exception.Create(STileShouldBeEmpty); 809 end; 810 end; 811 1144 812 function IntToStrRoman(Num: Integer): string; 1145 813 const … … 1309 977 FBoardUndo := TBoard.Create; 1310 978 History := THistory.Create; 1311 History.Game := Self;1312 979 Value2Chance := 0.1; 1313 980 end;
Note:
See TracChangeset
for help on using the changeset viewer.