Changeset 39
- Timestamp:
- Mar 10, 2014, 11:01:14 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Forms/UFormMain.lfm
r35 r39 101 101 Action = Core.AGameEndTurn 102 102 end 103 object MenuItem14: TMenuItem 104 Action = Core.AGameLoad 105 end 106 object MenuItem15: TMenuItem 107 Action = Core.AGameSave 108 end 103 109 object MenuItem5: TMenuItem 104 110 Caption = '-' -
trunk/Forms/UFormMain.pas
r35 r39 27 27 MenuItem12: TMenuItem; 28 28 MenuItem13: TMenuItem; 29 MenuItem14: TMenuItem; 30 MenuItem15: TMenuItem; 29 31 MenuItem2: TMenuItem; 30 32 MenuItem3: TMenuItem; … … 242 244 if Assigned(Cell) then begin 243 245 Core.Game.CurrentPlayer.View.FocusedCell := Cell; 244 StatusBar1.Panels[0].Text := '[' + IntToStr(Cell.Pos.X) + ', ' + IntToStr(Cell.Pos.Y) + '] (' + IntToStr(Cell.MovesFrom.Count) + ', ' + IntToStr(Cell.MovesTo.Count) + ')'; 246 StatusBar1.Panels[0].Text := '[' + IntToStr(Cell.Pos.X) + ', ' + IntToStr(Cell.Pos.Y) + 247 '] (' + IntToStr(Cell.MovesFrom.Count) + ', ' + IntToStr(Cell.MovesTo.Count) + ')'; 245 248 end else begin 246 249 Core.Game.CurrentPlayer.View.FocusedCell := nil; -
trunk/Forms/UFormNew.lfm
r38 r39 35 35 Height = 24 36 36 Top = 276 37 Width = 1 9437 Width = 175 38 38 Caption = 'Inaccessible places' 39 39 OnChange = CheckBoxVoidChange … … 92 92 Height = 22 93 93 Top = 184 94 Width = 9994 Width = 88 95 95 Caption = 'Map width:' 96 96 ParentColor = False … … 139 139 Height = 22 140 140 Top = 277 141 Width = 1 7141 Width = 15 142 142 Caption = '%' 143 143 ParentColor = False … … 173 173 Height = 22 174 174 Top = 232 175 Width = 106175 Width = 94 176 176 Caption = 'Map height:' 177 177 ParentColor = False … … 181 181 Height = 24 182 182 Top = 316 183 Width = 73183 Width = 68 184 184 Caption = 'Cities' 185 185 OnChange = CheckBoxCityChange … … 199 199 Height = 22 200 200 Top = 317 201 Width = 1 7201 Width = 15 202 202 Caption = '%' 203 203 ParentColor = False … … 248 248 TabOrder = 15 249 249 end 250 object ComboBoxGridType: TComboBox 251 Left = 320 252 Height = 32 253 Top = 376 254 Width = 208 255 ItemHeight = 0 256 Items.Strings = ( 257 'Hexagonal' 258 'Square' 259 ) 260 Style = csDropDownList 261 TabOrder = 16 262 end 263 object Label5: TLabel 264 Left = 224 265 Height = 22 266 Top = 376 267 Width = 79 268 Caption = 'Grid type:' 269 ParentColor = False 270 end 250 271 end -
trunk/Forms/UFormNew.lrt
r38 r39 17 17 TFORMNEW.RADIOGROUPGROWAMOUNT.CAPTION=Per turn grow amount 18 18 TFORMNEW.RADIOGROUPGROWCELLS.CAPTION=Growing cells 19 TFORMNEW.LABEL5.CAPTION=Grid type: -
trunk/Forms/UFormNew.pas
r38 r39 21 21 CheckBoxVoid: TCheckBox; 22 22 CheckBoxCity: TCheckBox; 23 ComboBoxGridType: TComboBox; 23 24 Label1: TLabel; 24 25 Label2: TLabel; 25 26 Label3: TLabel; 26 27 Label4: TLabel; 28 Label5: TLabel; 27 29 ListView1: TListView; 28 30 RadioGroupGrowCells: TRadioGroup; … … 194 196 RadioGroupGrowAmount.ItemIndex := Integer(Game.GrowAmount); 195 197 RadioGroupGrowCells.ItemIndex := Integer(Game.GrowCells); 198 ComboBoxGridType.ItemIndex := Integer(Game.MapType) - 1; 196 199 end; 197 200 … … 215 218 Game.GrowAmount := TGrowAmount(RadioGroupGrowAmount.ItemIndex); 216 219 Game.GrowCells := TGrowCells(RadioGroupGrowCells.ItemIndex); 220 Game.MapType := TMapType(ComboBoxGridType.ItemIndex + 1); 217 221 end; 218 222 -
trunk/Languages/xtactics.cs.po
r38 r39 38 38 msgstr "Ukončit tah hráče" 39 39 40 #: tcore.agameload.caption 41 msgid "Load" 42 msgstr "Načíst" 43 40 44 #: tcore.agamenew.caption 41 45 msgctxt "TCORE.AGAMENEW.CAPTION" … … 56 60 msgid "Restart game" 57 61 msgstr "Restartovat hru" 62 63 #: tcore.agamesave.caption 64 msgid "Save" 65 msgstr "Uložit" 58 66 59 67 #: tcore.asettings.caption … … 177 185 msgstr "%" 178 186 187 #: tformnew.label5.caption 188 msgid "Grid type:" 189 msgstr "Typ mřížky:" 190 179 191 #: tformnew.listview1.columns[0].caption 180 192 msgid "Name" … … 260 272 msgstr "tah" 261 273 274 #: ugame.scannotsetplayerstartcells 275 msgid "Cannot choose start cell for player" 276 msgstr "Nelze vybrat počáteční buňky hráčů." 277 262 278 #: ugame.scomputer 263 279 msgid "Computer" -
trunk/Languages/xtactics.po
r38 r39 29 29 msgstr "" 30 30 31 #: tcore.agameload.caption 32 msgid "Load" 33 msgstr "" 34 31 35 #: tcore.agamenew.caption 32 36 msgctxt "TCORE.AGAMENEW.CAPTION" … … 48 52 msgstr "" 49 53 54 #: tcore.agamesave.caption 55 msgid "Save" 56 msgstr "" 57 50 58 #: tcore.asettings.caption 51 59 msgctxt "tcore.asettings.caption" … … 165 173 msgstr "" 166 174 175 #: tformnew.label5.caption 176 msgid "Grid type:" 177 msgstr "" 178 167 179 #: tformnew.listview1.columns[0].caption 168 180 msgid "Name" … … 248 260 msgstr "" 249 261 262 #: ugame.scannotsetplayerstartcells 263 msgid "Cannot choose start cell for player" 264 msgstr "" 265 250 266 #: ugame.scomputer 251 267 msgid "Computer" -
trunk/UCore.lfm
r36 r39 52 52 OnExecute = ASettingsExecute 53 53 ShortCut = 120 54 end 55 object AGameSave: TAction 56 Caption = 'Save' 57 OnExecute = AGameSaveExecute 58 ShortCut = 16467 59 end 60 object AGameLoad: TAction 61 Caption = 'Load' 62 OnExecute = AGameLoadExecute 63 ShortCut = 16463 54 64 end 55 65 end … … 435 445 top = 360 436 446 end 447 object OpenDialog1: TOpenDialog 448 DefaultExt = '.xtmap' 449 left = 600 450 top = 155 451 end 452 object SaveDialog1: TSaveDialog 453 DefaultExt = '.xtmap' 454 left = 600 455 top = 88 456 end 437 457 end -
trunk/UCore.lrt
r34 r39 11 11 TCORE.ASETTINGS.CAPTION=Settings 12 12 TCORE.ASETTINGS.HINT=Application settings 13 TCORE.AGAMESAVE.CAPTION=Save 14 TCORE.AGAMELOAD.CAPTION=Load -
trunk/UCore.pas
r36 r39 14 14 15 15 TCore = class(TDataModule) 16 AGameSave: TAction; 17 AGameLoad: TAction; 16 18 ASettings: TAction; 17 19 ActionList1: TActionList; … … 24 26 ImageListLarge: TImageList; 25 27 ImageListSmall: TImageList; 28 OpenDialog1: TOpenDialog; 29 SaveDialog1: TSaveDialog; 26 30 XMLConfig1: TXMLConfig; 27 31 procedure AExitExecute(Sender: TObject); 28 32 procedure AGameEndExecute(Sender: TObject); 29 33 procedure AGameEndTurnExecute(Sender: TObject); 34 procedure AGameLoadExecute(Sender: TObject); 30 35 procedure AGameNewExecute(Sender: TObject); 31 36 procedure AGameRestartExecute(Sender: TObject); 37 procedure AGameSaveExecute(Sender: TObject); 32 38 procedure ASettingsExecute(Sender: TObject); 33 39 procedure CoolTranslator1Translate(Sender: TObject); … … 42 48 Game: TGame; 43 49 UseSingleView: Boolean; 50 LastMapFileName: string; 44 51 View: TView; 45 52 procedure Init; … … 114 121 end; 115 122 123 procedure TCore.AGameLoadExecute(Sender: TObject); 124 begin 125 OpenDialog1.FileName := LastMapFileName; 126 if OpenDialog1.Execute then begin 127 Game.Map.LoadFromFile(OpenDialog1.FileName); 128 LastMapFileName := OpenDialog1.FileName; 129 FormMain.Redraw; 130 end; 131 end; 132 116 133 procedure TCore.AGameNewExecute(Sender: TObject); 117 134 begin … … 132 149 end; 133 150 151 procedure TCore.AGameSaveExecute(Sender: TObject); 152 begin 153 SaveDialog1.FileName := ExtractFileDir(LastMapFileName); 154 if SaveDialog1.Execute then begin 155 Game.Map.SaveToFile(SaveDialog1.FileName); 156 LastMapFileName := SaveDialog1.FileName; 157 end; 158 end; 159 134 160 procedure TCore.ASettingsExecute(Sender: TObject); 135 161 begin … … 155 181 Game.SaveConfig(XMLConfig1, 'Game'); 156 182 XMLConfig1.SetValue('Language', CoolTranslator1.Language.Code); 183 XMLConfig1.SetValue('LastMapFileName', LastMapFileName); 157 184 FreeAndNil(Game); 158 185 end; … … 163 190 begin 164 191 FInitialized := True; 192 LastMapFileName := XMLConfig1.GetValue('LastMapFileName', ''); 165 193 CoolTranslator1.Language := CoolTranslator1.Languages.SearchByCode(XMLConfig1.GetValue('Language', '')); 166 194 for I := 0 to Game.Players.Count - 1 do -
trunk/UGame.pas
r38 r39 6 6 7 7 uses 8 Classes, SysUtils, ExtCtrls, Graphics, Contnrs, XMLConf; 8 Classes, SysUtils, ExtCtrls, Graphics, Contnrs, XMLConf, XMLRead, XMLWrite, 9 DOM; 9 10 10 11 const … … 46 47 47 48 TCellArray = array of TCell; 48 49 { TMap }50 51 TMap = class52 53 end;54 49 55 50 { TView } … … 80 75 end; 81 76 82 { T HexMap }83 84 T HexMap = class(TMap)77 { TMap } 78 79 TMap = class 85 80 private 86 FSize: TPoint;87 procedure SetSize(AValue: TPoint); 81 function GetSize: TPoint; virtual; 82 procedure SetSize(AValue: TPoint); virtual; 88 83 public 89 84 Game: TGame; 90 85 MaxPower: Integer; 91 86 DefaultCellSize: TPoint; 87 function IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; virtual; 88 function IsValidIndex(Index: TPoint): Boolean; virtual; 89 procedure Assign(Source: TMap); virtual; 90 procedure LoadFromFile(FileName: string); virtual; 91 procedure SaveToFile(FileName: string); virtual; 92 function PosToCell(Pos: TPoint; View: TView): TCell; virtual; 93 function CellToPos(Cell: TCell): TPoint; virtual; 94 procedure Grow(APlayer: TPlayer); virtual; 95 procedure ComputePlayerStats; virtual; 96 constructor Create; virtual; 97 destructor Destroy; override; 98 function GetCellNeighbours(Cell: TCell): TCellArray; virtual; 99 procedure Paint(Canvas: TCanvas; View: TView); virtual; 100 function GetPixelRect: TRect; virtual; 101 function GetAllCells: TCellArray; virtual; 102 procedure ForEachCells(Method: TMethod); virtual; 103 property Size: TPoint read GetSize write SetSize; 104 end; 105 106 { THexMap } 107 108 THexMap = class(TMap) 109 private 110 FSize: TPoint; 111 function GetSize: TPoint; override; 112 procedure SetSize(AValue: TPoint); override; 113 public 92 114 Cells: array of array of TCell; 93 function IsValidIndex(Index: TPoint): Boolean; 94 function GetCellNeighbours(Cell: TCell): TCellArray; 95 function PosToCell(Pos: TPoint; View: TView): TCell; 96 function CellToPos(Cell: TCell; View: TView): TPoint; 115 function IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; override; 116 procedure Assign(Source: TMap); virtual; 117 procedure LoadFromFile(FileName: string); override; 118 procedure SaveToFile(FileName: string); override; 119 function IsValidIndex(Index: TPoint): Boolean; override; 120 function GetCellNeighbours(Cell: TCell): TCellArray; override; 121 function PosToCell(Pos: TPoint; View: TView): TCell; override; 122 function CellToPos(Cell: TCell): TPoint; override; 97 123 function GetHexagonPolygon(Pos: TPoint; HexSize: TPoint): TPointArray; 98 procedure Paint(Canvas: TCanvas; View: TView); 99 constructor Create; 124 procedure Paint(Canvas: TCanvas; View: TView); override; 125 constructor Create; override; 100 126 destructor Destroy; override; 101 procedure Grow(APlayer: TPlayer); 102 procedure ComputePlayerStats; 103 function GetPixelRect: TRect; 127 function GetAllCells: TCellArray; override; 128 function GetPixelRect: TRect; override; 129 end; 130 131 { TSquareMap } 132 133 TSquareMap = class(TMap) 134 private 135 FSize: TPoint; 136 function GetSize: TPoint; override; 137 procedure SetSize(AValue: TPoint); override; 138 public 139 Cells: array of array of TCell; 140 function IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; override; 141 function IsValidIndex(Index: TPoint): Boolean; override; 142 function PosToCell(Pos: TPoint; View: TView): TCell; override; 143 function CellToPos(Cell: TCell): TPoint; override; 144 function GetCellNeighbours(Cell: TCell): TCellArray; override; 145 function GetAllCells: TCellArray; override; 146 function GetPixelRect: TRect; override; 147 procedure Paint(Canvas: TCanvas; View: TView); override; 148 constructor Create; override; 149 destructor Destroy; override; 104 150 property Size: TPoint read FSize write SetSize; 105 151 end; 106 107 152 108 153 TPlayerMode = (pmHuman, pmComputer); … … 162 207 TGrowAmount = (gaByOne, gaBySquareRoot); 163 208 TGrowCells = (gcNone, gcPlayerCities, gcPlayerAll); 209 TMapType = (mtNone, mtHexagon, mtSquare); 164 210 165 211 TGame = class 166 212 private 213 FMapType: TMapType; 167 214 FOnMove: TMoveEvent; 168 215 FOnWin: TWinEvent; … … 171 218 procedure MoveAll(Player: TPlayer); 172 219 procedure ClearMovesFromCell(Cell: TCell); 220 procedure SetMapType(AValue: TMapType); 173 221 procedure SetMove(CellFrom, CellTo: TCell; Power: Integer); 174 222 procedure SetRunning(AValue: Boolean); … … 176 224 public 177 225 Players: TPlayers; 178 Map: T HexMap;226 Map: TMap; 179 227 VoidEnabled: Boolean; 180 228 VoidPercentage: Integer; … … 195 243 procedure New; 196 244 property Running: Boolean read FRunning write SetRunning; 245 property MapType: TMapType read FMapType write SetMapType; 197 246 published 198 247 property OnMove: TMoveEvent read FOnMove write FOnMove; … … 218 267 SHuman = 'Human'; 219 268 SComputer = 'Computer'; 269 SCannotSetPlayerStartCells = 'Cannot choose start cell for player'; 220 270 221 271 procedure InitStrings; … … 235 285 Result := (A.Left = B.Left) and (A.Top = B.Top) and 236 286 (A.Right = B.Right) and (A.Bottom = B.Bottom); 287 end; 288 289 function PtInRect(const Rect: TRect; Pos: TPoint): Boolean; 290 begin 291 Result := (Pos.X >= Rect.Left) and (Pos.Y >= Rect.Top) and 292 (Pos.X <= Rect.Right) and (Pos.Y <= Rect.Bottom); 237 293 end; 238 294 … … 244 300 Count := Length(Points) ; 245 301 J := Count - 1; 246 for K := 0 to Count -1 do begin302 for K := 0 to Count - 1 do begin 247 303 if ((Points[K].Y <= Pos.Y) and (Pos.Y < Points[J].Y)) or 248 304 ((Points[J].Y <= Pos.Y) and (Pos.Y < Points[K].Y)) then … … 257 313 end; 258 314 259 function IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; 315 { TSquareMap } 316 317 function TSquareMap.GetSize: TPoint; 318 begin 319 Result := FSize; 320 end; 321 322 procedure TSquareMap.SetSize(AValue: TPoint); 323 var 324 X, Y: Integer; 325 NewCell: TCell; 326 C: Integer; 327 begin 328 if (FSize.X <> AValue.X) or (FSize.Y <> AValue.Y) then begin 329 // Free previous 330 for Y := 0 to FSize.Y - 1 do 331 for X := 0 to FSize.X - 1 do begin 332 TCell(Cells[Y, X]).Destroy; 333 end; 334 FSize := AValue; 335 // Allocate and init new 336 SetLength(Cells, FSize.Y, FSize.X); 337 for Y := 0 to FSize.Y - 1 do 338 for X := 0 to FSize.X - 1 do begin 339 NewCell := TCell.Create; 340 NewCell.Pos := Point(X, Y); 341 Cells[Y, X] := NewCell; 342 end; 343 end; 344 end; 345 346 function TSquareMap.IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; 260 347 var 261 348 DX: Integer; … … 267 354 DX := Cell2.Pos.X - Cell1.Pos.X; 268 355 DY := Cell2.Pos.Y - Cell1.Pos.Y; 269 Result := (Abs(DX) <= 1) and (Abs(DY) <= 1) and 270 ((((MinY mod 2) = 1) and 271 not ((DX = 1) and (DY = -1)) and 272 not ((DX = -1) and (DY = 1))) or 273 (((MinY mod 2) = 0) and 274 not ((DX = -1) and (DY = -1)) and 275 not ((DX = 1) and (DY = 1)))); 356 Result := (Abs(DX) <= 1) and (Abs(DY) <= 1); 276 357 Result := Result and not (Cell1 = Cell2); 358 end; 359 360 function TSquareMap.IsValidIndex(Index: TPoint): Boolean; 361 begin 362 Result := (Index.X >= 0) and (Index.X < Size.X) and 363 (Index.Y >= 0) and (Index.Y < Size.Y); 364 end; 365 366 function TSquareMap.PosToCell(Pos: TPoint; View: TView): TCell; 367 var 368 CX, CY: Integer; 369 X, Y: Double; 370 HexSize: TFloatPoint; 371 CellSize: TFloatPoint; 372 Frame: TRect; 373 begin 374 // TODO: This is implemented as simple sequence lookup. Needs some faster algorithm 375 Result := nil; 376 CellSize := FloatPoint(DefaultCellSize.X, DefaultCellSize.Y); 377 HexSize := FloatPoint(DefaultCellSize.X, DefaultCellSize.Y); 378 with View do 379 for CY := Trunc(SourceRect.Top / CellSize.Y) to Trunc(SourceRect.Bottom / CellSize.Y) + 1 do 380 for CX := Trunc(SourceRect.Left / CellSize.X) to Trunc(SourceRect.Right / CellSize.X) + 1 do begin 381 X := CX; 382 Y := CY; 383 if (CX >= 0) and (CY >= 0) and (CY < Size.Y) and (CX < Size.X) then 384 if Cells[CY, CX].Terrain <> ttVoid then begin 385 Frame := Rect(Trunc(X * CellSize.X - HexSize.X / 2), 386 Trunc(Y * CellSize.Y - HexSize.Y / 2), 387 Trunc(X * CellSize.X + HexSize.X / 2), 388 Trunc(Y * CellSize.Y + HexSize.Y / 2)); 389 if PtInRect(Frame, Pos) then begin 390 Result := Cells[CY, CX]; 391 Exit; 392 end; 393 end; 394 end; 395 end; 396 397 function TSquareMap.CellToPos(Cell: TCell): TPoint; 398 var 399 CX, CY: Integer; 400 X, Y: Double; 401 HexSize: TFloatPoint; 402 CellSize: TFloatPoint; 403 Points: array of TPoint; 404 begin 405 CellSize := FloatPoint(DefaultCellSize.X, DefaultCellSize.Y); 406 HexSize := FloatPoint(DefaultCellSize.X, DefaultCellSize.Y); 407 X := Cell.Pos.X; 408 Y := Cell.Pos.Y; 409 410 Result.X := Trunc(X * CellSize.X); 411 Result.Y := Trunc(Y * CellSize.Y); 412 end; 413 414 function TSquareMap.GetCellNeighbours(Cell: TCell): TCellArray; 415 var 416 X, Y: Integer; 417 begin 418 SetLength(Result, 0); 419 for Y := -1 to 1 do 420 for X := -1 to 1 do 421 if IsValidIndex(Point(Cell.Pos.X + X, Cell.Pos.Y + Y)) and 422 IsCellsNeighbor(Cell, Cells[Cell.Pos.Y + Y, Cell.Pos.X + X]) then begin 423 SetLength(Result, Length(Result) + 1); 424 Result[Length(Result) - 1] := Cells[Cell.Pos.Y + Y, Cell.Pos.X + X]; 425 end; 426 end; 427 428 function TSquareMap.GetAllCells: TCellArray; 429 var 430 X: Integer; 431 Y: Integer; 432 I: Integer; 433 begin 434 SetLength(Result, Size.Y * Size.X); 435 for Y := 0 to Size.Y - 1 do 436 for X := 0 to Size.X - 1 do 437 Result[Y * Size.X + X] := Cells[Y, X]; 438 end; 439 440 function TSquareMap.GetPixelRect: TRect; 441 begin 442 Result := Bounds(Trunc(-0.5 * DefaultCellSize.X), 443 Trunc(-0.5 * DefaultCellSize.Y), 444 Trunc((Size.X + 0.5) * DefaultCellSize.X), 445 Trunc(((Size.Y + 0.5) * 0.78) * DefaultCellSize.Y)); 446 end; 447 448 procedure TSquareMap.Paint(Canvas: TCanvas; View: TView); 449 var 450 CX, CY: Integer; 451 X, Y: Double; 452 CellSizeZoomed: TFloatPoint; 453 CellSize: TFloatPoint; 454 HexSize: TFloatPoint; 455 I: Integer; 456 Points: array of TPoint; 457 Cell: TCell; 458 PosFrom, PosTo: TPoint; 459 460 procedure PaintHexagon(Pos: TPoint; Text: string); 461 begin 462 with Canvas do begin 463 if Assigned(View.FocusedCell) and (View.FocusedCell = TCell(Cells[CY, CX])) then begin 464 Pen.Color := clYellow; 465 Pen.Style := psSolid; 466 Pen.Width := 1; 467 end else 468 if TCell(Cells[CY, CX]).Terrain = ttCity then begin 469 // Cannot set clear border as it will display shifted on gtk2 470 //Pen.Style := psClear; 471 Pen.Color := clBlack; 472 Pen.Style := psSolid; 473 Pen.Width := 3; 474 end else begin 475 // Cannot set clear border as it will display shifted on gtk2 476 //Pen.Style := psClear; 477 Pen.Color := Brush.Color; 478 Pen.Style := psSolid; 479 Pen.Width := 0; 480 end; 481 FillRect(Trunc(Pos.X - HexSize.X / 2), Trunc(Pos.Y - HexSize.Y / 2), Trunc(Pos.X + HexSize.X / 2), Trunc(Pos.Y + HexSize.Y / 2)); 482 //Rectangle(Trunc(Pos.X), Trunc(Pos.Y), Trunc(Pos.X + HexSize.X), Trunc(Pos.Y + HexSize.Y)); 483 Pen.Style := psSolid; 484 Font.Color := clWhite; 485 Font.Size := Trunc(12 * View.Zoom); 486 TextOut(Round(Pos.X) - TextWidth(Text) div 2, Round(Pos.Y) - TextHeight(Text) div 2, Text); 487 end; 488 end; 489 490 begin 491 CellSize := FloatPoint(DefaultCellSize.X, DefaultCellSize.Y); 492 HexSize := FloatPoint(DefaultCellSize.X * View.Zoom, DefaultCellSize.Y * View.Zoom); 493 CellSizeZoomed := FloatPoint(CellSize.X * View.Zoom, CellSize.Y * View.Zoom); 494 with Canvas, View do try 495 Lock; 496 for CY := Trunc(SourceRect.Top / CellSize.Y) to Trunc(SourceRect.Bottom / CellSize.Y) + 1 do 497 for CX := Trunc(SourceRect.Left / CellSize.X) to Trunc(SourceRect.Right / CellSize.X) + 1 do begin 498 X := CX; 499 Y := CY; 500 if (CX >= 0) and (CY >= 0) and (CY < Size.Y) and (CX < Size.X) then begin 501 Cell := Cells[CY, CX]; 502 if Cell.Terrain <> ttVoid then begin 503 if Assigned(SelectedCell) and (SelectedCell = TCell(Cells[CY, CX])) then Brush.Color := clGreen 504 else if Assigned(SelectedCell) and IsCellsNeighbor(SelectedCell, TCell(Cells[CY, CX])) then Brush.Color := clPurple 505 else Brush.Color := Cell.GetColor; 506 Pen.Color := clBlack; 507 PaintHexagon(View.CellToCanvasPos(Point(Trunc(X * CellSize.X), 508 Trunc(Y * CellSize.Y))), 509 IntToStr(Cell.GetAvialPower)); 510 // Draw arrows 511 Pen.Color := clCream; 512 for I := 0 to Cell.MovesFrom.Count - 1 do begin 513 PosFrom := CellToPos(Cell); 514 PosTo := CellToPos(TMove(Cell.MovesFrom[I]).CellTo); 515 if TMove(Cell.MovesFrom[I]).CountRepeat > 0 then Pen.Width := 2 516 else Pen.Width := 1; 517 Line(View.CellToCanvasPos(Point(Trunc(PosFrom.X + (PosTo.X - PosFrom.X) / 4), 518 Trunc(PosFrom.Y + (PosTo.Y - PosFrom.Y) / 4))), 519 View.CellToCanvasPos(Point(Trunc(PosFrom.X + (PosTo.X - PosFrom.X) / 2), 520 Trunc(PosFrom.Y + (PosTo.Y - PosFrom.Y) / 2)))); 521 Pen.Width := 1; 522 end; 523 end; 524 end; 525 end; 526 finally 527 Unlock; 528 end; 529 end; 530 531 constructor TSquareMap.Create; 532 begin 533 inherited; 534 end; 535 536 destructor TSquareMap.Destroy; 537 begin 538 inherited Destroy; 539 end; 540 541 { TMap } 542 543 function TMap.GetSize: TPoint; 544 begin 545 Result:= Point(0, 0); 546 end; 547 548 procedure TMap.SetSize(AValue: TPoint); 549 begin 550 551 end; 552 553 function TMap.IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; 554 begin 555 Result := False; 556 end; 557 558 function TMap.IsValidIndex(Index: TPoint): Boolean; 559 begin 560 Result := False; 561 end; 562 563 procedure TMap.Assign(Source: TMap); 564 begin 565 MaxPower := Source.MaxPower; 566 Game := Source.Game; 567 Size := Source.Size; 568 DefaultCellSize := Source.DefaultCellSize; 569 end; 570 571 procedure TMap.LoadFromFile(FileName: string); 572 begin 573 574 end; 575 576 procedure TMap.SaveToFile(FileName: string); 577 begin 578 579 end; 580 581 function TMap.PosToCell(Pos: TPoint; View: TView): TCell; 582 begin 583 Result := nil; 584 end; 585 586 function TMap.CellToPos(Cell: TCell): TPoint; 587 begin 588 Result := Point(0, 0); 589 end; 590 591 procedure TMap.Grow(APlayer: TPlayer); 592 var 593 I: Integer; 594 Addition: Integer; 595 Cells: TCellArray; 596 begin 597 Cells := GetAllCells; 598 for I := 0 to Length(Cells) - 1 do 599 with TCell(Cells[I]) do begin 600 if (Player = APlayer) and ((Game.GrowCells = gcPlayerAll) or 601 ((Game.GrowCells = gcPlayerCities) and (Terrain = ttCity))) then begin 602 if Game.GrowAmount = gaByOne then Addition := 1 603 else if Game.GrowAmount = gaBySquareRoot then begin 604 Addition := Trunc(Sqrt(Power)); 605 if Addition = 0 then Addition := 1; 606 end; 607 Power := Power + Addition; 608 if Power > MaxPower then Power := MaxPower; 609 end; 610 end; 611 end; 612 613 procedure TMap.ComputePlayerStats; 614 var 615 Cells: TCellArray; 616 I: Integer; 617 begin 618 Cells := GetAllCells; 619 for I := 0 to Length(Cells) - 1 do 620 with Cells[I] do begin 621 if Assigned(Player) then begin 622 Player.TotalCells := Player.TotalCells + 1; 623 Player.TotalUnits := Player.TotalUnits + Power; 624 end; 625 end; 626 end; 627 628 constructor TMap.Create; 629 begin 630 MaxPower := 99; 631 DefaultCellSize := Point(62, 62); 632 end; 633 634 destructor TMap.Destroy; 635 begin 636 Size := Point(0, 0); 637 inherited Destroy; 638 end; 639 640 function TMap.GetCellNeighbours(Cell: TCell): TCellArray; 641 begin 642 643 end; 644 645 procedure TMap.Paint(Canvas: TCanvas; View: TView); 646 begin 647 648 end; 649 650 function TMap.GetPixelRect: TRect; 651 var 652 Cells: TCellArray; 653 I: Integer; 654 CellPos: TPoint; 655 begin 656 Result := Rect(0, 0, 0, 0); 657 // This is generic iterative algorithm to determine map pixel size 658 Cells := GetAllCells; 659 for I := 0 to Length(Cells) - 1 do begin 660 CellPos := CellToPos(Cells[I]); 661 if I = 0 then Result := Rect(CellPos.X, CellPos.Y, CellPos.X, CellPos.Y) 662 else begin 663 if CellPos.X > Result.Right then Result.Right := CellPos.X; 664 if CellPos.Y > Result.Bottom then Result.Bottom := CellPos.Y; 665 if CellPos.X < Result.Left then Result.Left := CellPos.X; 666 if CellPos.Y < Result.Top then Result.Top := CellPos.Y; 667 end; 668 end; 669 end; 670 671 672 function TMap.GetAllCells: TCellArray; 673 begin 674 675 end; 676 677 procedure TMap.ForEachCells(Method: TMethod); 678 begin 679 277 680 end; 278 681 … … 464 867 procedure TPlayer.ComputerTurn; 465 868 var 869 AllCells: TCellArray; 466 870 Cells: TCellArray; 467 871 X, Y: Integer; … … 470 874 TotalAttackPower: Integer; 471 875 I: Integer; 876 C: Integer; 472 877 CanAttack: Integer; 473 878 begin 474 for Y := 0 to Game.Map.Size.Y - 1 do475 for X := 0 to Game.Map.Size.X- 1 do476 with TCell(Game.Map.Cells[Y, X])do begin879 AllCells := Game.Map.GetAllCells; 880 for C := 0 to Length(AllCells) - 1 do 881 with AllCells[C] do begin 477 882 if (Terrain <> ttVoid) and (Player <> Self) then begin 478 883 // Attack to not owned cell yet 479 884 // Count own possible power 480 Cells := Game.Map.GetCellNeighbours( Game.Map.Cells[Y, X]);885 Cells := Game.Map.GetCellNeighbours(AllCells[C]); 481 886 TotalPower := 0; 482 887 for I := 0 to Length(Cells) - 1 do … … 493 898 if Cells[I].GetAvialPower < AttackPower then 494 899 AttackPower := Cells[I].GetAvialPower; 495 Game.SetMove(Cells[I], Game.Map.Cells[Y, X], AttackPower);900 Game.SetMove(Cells[I], AllCells[C], AttackPower); 496 901 TotalAttackPower := TotalAttackPower + AttackPower; 497 902 end; … … 502 907 // We need to move available power to borders to be available for attacks 503 908 // or defense 504 Cells := Game.Map.GetCellNeighbours( Game.Map.Cells[Y, X]);909 Cells := Game.Map.GetCellNeighbours(AllCells[C]); 505 910 CanAttack := 0; 506 911 for I := 0 to Length(Cells) - 1 do … … 512 917 // For simplicty just try to balance inner area cells power 513 918 for I := 0 to Length(Cells) - 1 do 514 if (Cells[I].Player = Self) and (Cells[I].Power < Game.Map.Cells[Y, X].GetAvialPower) then begin515 Game.SetMove( Game.Map.Cells[Y, X], Cells[I], (Game.Map.Cells[Y, X].GetAvialPower - Cells[I].Power) div 2);919 if (Cells[I].Player = Self) and (Cells[I].Power < AllCells[C].GetAvialPower) then begin 920 Game.SetMove(AllCells[C], Cells[I], (AllCells[C].GetAvialPower - Cells[I].Power) div 2); 516 921 end; 517 922 end; … … 528 933 NewSelectedCell := Game.Map.PosToCell(CanvasToCellPos(Pos), Self); 529 934 if Assigned(NewSelectedCell) then begin 530 if Assigned(SelectedCell) and IsCellsNeighbor(NewSelectedCell, SelectedCell) then begin935 if Assigned(SelectedCell) and Game.Map.IsCellsNeighbor(NewSelectedCell, SelectedCell) then begin 531 936 Game.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power); 532 937 SelectedCell := nil; … … 610 1015 while I < Moves.Count do 611 1016 with TMove(Moves[I]) do begin 1017 if CountOnce > 0 then begin 612 1018 if CellFrom.Player = Player then begin 613 1019 if CellTo.Player = Player then begin … … 633 1039 CountOnce := 0; 634 1040 end; 1041 end; 635 1042 Inc(I); 636 1043 end; … … 649 1056 if TMove(Moves[I]).CellFrom = Cell then 650 1057 Moves.Delete(I); 1058 end; 1059 1060 procedure TGame.SetMapType(AValue: TMapType); 1061 var 1062 OldMap: TMap; 1063 begin 1064 if FMapType = AValue then Exit; 1065 OldMap := Map; 1066 case AValue of 1067 mtNone: Map := TMap.Create; 1068 mtHexagon: Map := THexMap.Create; 1069 mtSquare: Map := TSquareMap.Create; 1070 end; 1071 Map.Assign(OldMap); 1072 OldMap.Free; 1073 FMapType := AValue; 651 1074 end; 652 1075 … … 731 1154 begin 732 1155 with Config do begin 1156 SetValue(Path + '/GridType', Integer(MapType)); 733 1157 SetValue(Path + '/VoidEnabled', VoidEnabled); 734 1158 SetValue(Path + '/VoidPercentage', VoidPercentage); … … 745 1169 begin 746 1170 with Config do begin 1171 MapType := TMapType(GetValue(Path + '/GridType', Integer(mtHexagon))); 747 1172 VoidEnabled := GetValue(Path + '/VoidEnabled', True); 748 1173 VoidPercentage := GetValue(Path + '/VoidPercentage', 20); … … 809 1234 begin 810 1235 Moves := TObjectList.Create; 811 Map := T HexMap.Create;1236 Map := TMap.Create; 812 1237 Players := TPlayers.Create; 813 1238 … … 848 1273 StartCell: TCell; 849 1274 Counter: Integer; 1275 AllCells: TCellArray; 1276 C: Integer; 850 1277 begin 851 1278 TurnCounter := 1; 852 1279 Moves.Clear; 853 for Y := 0 to Map.Size.Y - 1 do854 for X := 0 to Map.Size.X- 1 do855 with Map.Cells[Y, X] do begin1280 AllCells := Map.GetAllCells; 1281 for C := 0 to Length(AllCells) - 1 do 1282 with AllCells[C] do begin 856 1283 if VoidEnabled and (Random < VoidPercentage / 100) then Terrain := ttVoid 857 1284 else begin … … 870 1297 Counter := 0; 871 1298 while not Assigned(StartCell) or Assigned(StartCell.Player) do begin 872 StartCell := Map.Cells[Random(Map.Size.Y), Random(Map.Size.X)];1299 StartCell := AllCells[Random(Length(AllCells))]; 873 1300 Inc(Counter); 874 1301 if Counter > 100 then 875 raise Exception.Create( 'Cannot choose start cell for player');1302 raise Exception.Create(SCannotSetPlayerStartCells); 876 1303 end; 877 1304 if CityEnabled then StartCell.Terrain := ttCity … … 902 1329 end; 903 1330 1331 function THexMap.GetSize: TPoint; 1332 begin 1333 Result := FSize; 1334 end; 1335 904 1336 procedure THexMap.SetSize(AValue: TPoint); 905 1337 var … … 924 1356 end; 925 1357 end; 1358 end; 1359 1360 function THexMap.IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; 1361 var 1362 DX: Integer; 1363 DY: Integer; 1364 MinY: Integer; 1365 begin 1366 if Cell1.Pos.Y < Cell2.Pos.Y then MinY:= Cell1.Pos.Y 1367 else MinY := Cell2.Pos.Y; 1368 DX := Cell2.Pos.X - Cell1.Pos.X; 1369 DY := Cell2.Pos.Y - Cell1.Pos.Y; 1370 Result := (Abs(DX) <= 1) and (Abs(DY) <= 1) and 1371 ((((MinY mod 2) = 1) and 1372 not ((DX = 1) and (DY = -1)) and 1373 not ((DX = -1) and (DY = 1))) or 1374 (((MinY mod 2) = 0) and 1375 not ((DX = -1) and (DY = -1)) and 1376 not ((DX = 1) and (DY = 1)))); 1377 Result := Result and not (Cell1 = Cell2); 1378 end; 1379 1380 procedure THexMap.Assign(Source: TMap); 1381 begin 1382 end; 1383 1384 procedure THexMap.LoadFromFile(FileName: string); 1385 var 1386 Doc: TXMLDocument; 1387 begin 1388 try 1389 ReadXMLFile(Doc, FileName); 1390 if Doc.DocumentElement.TagName <> 'Map' then 1391 raise Exception.Create('Invalid map format'); 1392 finally 1393 Doc.Free; 1394 end; 1395 inherited LoadFromFile(FileName); 1396 end; 1397 1398 procedure THexMap.SaveToFile(FileName: string); 1399 var 1400 Doc: TXMLDocument; 1401 RootNode: TDOMNode; 1402 begin 1403 try 1404 Doc := TXMLDocument.Create; 1405 RootNode := Doc.CreateElement('Map'); 1406 Doc.Appendchild(RootNode); 1407 WriteXMLFile(Doc, FileName); 1408 finally 1409 Doc.Free; 1410 end; 1411 inherited SaveToFile(FileName); 926 1412 end; 927 1413 … … 980 1466 end; 981 1467 982 function THexMap.CellToPos(Cell: TCell ; View: TView): TPoint;1468 function THexMap.CellToPos(Cell: TCell): TPoint; 983 1469 var 984 1470 CX, CY: Integer; … … 1073 1559 Pen.Color := clCream; 1074 1560 for I := 0 to Cell.MovesFrom.Count - 1 do begin 1075 PosFrom := CellToPos(Cell , View);1076 PosTo := CellToPos(TMove(Cell.MovesFrom[I]).CellTo , View);1561 PosFrom := CellToPos(Cell); 1562 PosTo := CellToPos(TMove(Cell.MovesFrom[I]).CellTo); 1077 1563 if TMove(Cell.MovesFrom[I]).CountRepeat > 0 then Pen.Width := 2 1078 1564 else Pen.Width := 1; … … 1093 1579 constructor THexMap.Create; 1094 1580 begin 1095 DefaultCellSize := Point(62, 62); 1096 MaxPower := 99; 1581 inherited; 1097 1582 end; 1098 1583 1099 1584 destructor THexMap.Destroy; 1100 1585 begin 1101 Size := Point(0, 0);1102 1586 inherited Destroy; 1103 1587 end; 1104 1588 1105 procedure THexMap.Grow(APlayer: TPlayer); 1106 var 1107 X, Y: Integer; 1108 Addition: Integer; 1109 begin 1589 function THexMap.GetAllCells: TCellArray; 1590 var 1591 X: Integer; 1592 Y: Integer; 1593 I: Integer; 1594 begin 1595 SetLength(Result, Size.Y * Size.X); 1110 1596 for Y := 0 to Size.Y - 1 do 1111 1597 for X := 0 to Size.X - 1 do 1112 with TCell(Cells[Y, X]) do begin 1113 if (Player = APlayer) and ((Game.GrowCells = gcPlayerAll) or 1114 ((Game.GrowCells = gcPlayerCities) and (Terrain = ttCity))) then begin 1115 if Game.GrowAmount = gaByOne then Addition := 1 1116 else if Game.GrowAmount = gaBySquareRoot then begin 1117 Addition := Trunc(Sqrt(Power)); 1118 if Addition = 0 then Addition := 1; 1119 end; 1120 Power := Power + Addition; 1121 if Power > MaxPower then Power := MaxPower; 1122 end; 1123 end; 1124 end; 1125 1126 procedure THexMap.ComputePlayerStats; 1127 var 1128 X, Y: Integer; 1129 begin 1130 for Y := 0 to Size.Y - 1 do 1131 for X := 0 to Size.X - 1 do 1132 with Cells[Y, X] do begin 1133 if Assigned(Player) then begin 1134 Player.TotalCells := Player.TotalCells + 1; 1135 Player.TotalUnits := Player.TotalUnits + Power; 1136 end; 1137 end; 1598 Result[Y * Size.X + X] := Cells[Y, X]; 1138 1599 end; 1139 1600
Note:
See TracChangeset
for help on using the changeset viewer.