- Timestamp:
- Nov 16, 2014, 2:31:27 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Forms/UFormMove.lfm
r75 r88 14 14 object SpinEditOnce: TSpinEdit 15 15 Left = 208 16 Height = 3 516 Height = 32 17 17 Top = 40 18 18 Width = 98 … … 23 23 object Label1: TLabel 24 24 Left = 16 25 Height = 2 525 Height = 22 26 26 Top = 40 27 Width = 5427 Width = 46 28 28 Caption = 'Once:' 29 29 ParentColor = False … … 50 50 object Label2: TLabel 51 51 Left = 24 52 Height = 2 552 Height = 22 53 53 Top = 136 54 Width = 10054 Width = 87 55 55 Caption = 'Every turn:' 56 56 ParentColor = False … … 58 58 object SpinEditRepeat: TSpinEdit 59 59 Left = 208 60 Height = 3 560 Height = 32 61 61 Top = 128 62 62 Width = 98 … … 131 131 object Label3: TLabel 132 132 Left = 16 133 Height = 2 5133 Height = 22 134 134 Top = 8 135 Width = 1 45135 Width = 127 136 136 Caption = 'Win probability:' 137 137 ParentColor = False … … 139 139 object LabelWinProbability: TLabel 140 140 Left = 264 141 Height = 2 5141 Height = 22 142 142 Top = 8 143 143 Width = 15 -
trunk/Forms/UFormMove.pas
r72 r88 78 78 LabelWinProbability.Caption := 79 79 IntToStr(Round(Core.Game.AttackProbability(AttackCount + SpinEditOnce.Value, 80 DefendCount , 1) * 100)) + ' %';80 DefendCount) * 100)) + ' %'; 81 81 end; 82 82 -
trunk/UGame.pas
r86 r88 111 111 TCanvasEx = class(TCanvas) 112 112 procedure TextOutEx(X,Y: Integer; const Text: string; MovePen: Boolean = True); 113 procedure PolygonEx(const Points: array of TPoint; Winding: Boolean); 113 114 end; 114 115 … … 278 279 procedure IncreaseMoves; 279 280 procedure Process; 281 procedure FallBack; 282 function AttackersCount(Cell: TCell): Integer; 280 283 end; 281 284 … … 343 346 FRunning: Boolean; 344 347 LoadedImageFileName: string; 348 ProbabilityMatrix: array of array of Single; 345 349 procedure Attack(var AttackPower, DefendPower: Integer); 346 350 procedure MoveAll(Player: TPlayer); … … 371 375 FileName: string; 372 376 FogOfWar: Boolean; 373 function AttackProbability(AttackCount, DefendCount , Depth: Integer): Double;377 function AttackProbability(AttackCount, DefendCount: Integer): Double; 374 378 procedure LoadConfig(Config: TXmlConfig; Path: string); 375 379 procedure SaveConfig(Config: TXmlConfig; Path: string); … … 703 707 end; 704 708 709 procedure TCanvasEx.PolygonEx(const Points: array of TPoint; Winding: Boolean); 710 begin 711 //Changing; 712 //RequiredState([csHandleValid, csBrushValid, csPenValid]); 713 LCLIntf.Polygon(Handle, @Points[0], Length(Points), Winding); 714 //Changed; 715 end; 716 717 705 718 { TCells } 706 719 … … 1232 1245 Points[I] := View.CellToCanvasPos(Cell.Polygon[I]); 1233 1246 Brush.Style := bsSolid; 1234 Polygon(Points, False, 0, Length(Points)); 1247 //Polygon(Points, False, 0, Length(Points)); 1248 TCanvasEx(Canvas).PolygonEx(Points, False); 1249 //MoveTo(Points[0].X, Points[0].Y); 1250 //LineTo(Points[1].X, Points[1].Y); 1235 1251 1236 1252 // Show cell text … … 1789 1805 1790 1806 // Sort descending to attack cells with higher power first 1791 // Higher power enemy cells grow faster and is more dangerous1807 // Higher power enemy cells can grow faster and is more dangerous 1792 1808 TargetCells.Sort(CellCompareDescending); 1793 1809 … … 1828 1844 NewTargetCells: TCells; 1829 1845 Cells2: TCells; 1846 MovedPower: Integer; 1830 1847 begin 1831 1848 // We need to move available power to borders to be available for attacks … … 1882 1899 Inc(CanAttack); 1883 1900 end; 1884 if CanAttack = 0 then 1885 Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), TCell(Neighbors[I]).GetAvialPower, False); 1901 if CanAttack = 0 then begin 1902 MovedPower := TCell(Neighbors[I]).GetAvialPower; 1903 if (TCell(TargetCells[C]).GetAvialPower + TCell(TargetCells[C]).GetAttackPower + MovedPower) > Game.Map.MaxPower then 1904 MovedPower := Game.Map.MaxPower - TCell(TargetCells[C]).GetAvialPower - TCell(TargetCells[C]).GetAttackPower; 1905 Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), MovedPower, False); 1906 end; 1886 1907 end; 1887 1908 TCell(Neighbors[I]).Mark := True; … … 1920 1941 InnerMoves; 1921 1942 IncreaseMoves; 1943 //FallBack; 1922 1944 CellProcessDirection := not CellProcessDirection; 1945 end; 1946 1947 procedure TComputer.FallBack; 1948 var 1949 C: Integer; 1950 I: Integer; 1951 AllCells: TCells; 1952 BorderCells: TCells; 1953 EnemyPower: Integer; 1954 begin 1955 BorderCells := TCells.Create; 1956 BorderCells.OwnsObjects := False; 1957 AllCells := Game.Map.Cells; 1958 1959 // Get list of border cells 1960 for C := 0 to AllCells.Count - 1 do 1961 with TCell(AllCells[C]) do begin 1962 if (Terrain <> ttVoid) and (Player = Game.CurrentPlayer) then begin 1963 if AttackersCount(TCell(AllCells[C])) > 0 then 1964 BorderCells.Add(AllCells[C]); 1965 end; 1966 end; 1967 1968 // Move all units back to inner area from weak border cells 1969 for C := 0 to BorderCells.Count - 1 do 1970 with TCell(BorderCells[C]) do begin 1971 // Calculate enemy power 1972 // TODO: Do not sum different enemy power to one value 1973 EnemyPower := 0; 1974 for I := 0 to Neighbors.Count - 1 do 1975 if (TCell(Neighbors[I]).Player <> Game.CurrentPlayer) and (TCell(Neighbors[I]).Player <> nil) then begin 1976 Inc(EnemyPower, TCell(Neighbors[I]).Power); 1977 end; 1978 if EnemyPower > (GetAvialPower + GetAttackPower) then begin 1979 // Fallback 1980 for I := MovesTo.Count - 1 downto 0 do 1981 TUnitMove(MovesTo[I]).Free; 1982 for I := 0 to Neighbors.Count - 1 do 1983 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) and (AttackersCount(TCell(Neighbors[I])) = 0) then begin 1984 1985 Game.SetMove(TCell(BorderCells[C]), TCell(Neighbors[I]), GetAvialPower, False); 1986 Break; 1987 end; 1988 end; 1989 end; 1990 1991 BorderCells.Free; 1992 end; 1993 1994 function TComputer.AttackersCount(Cell: TCell): Integer; 1995 var 1996 I: Integer; 1997 begin 1998 Result := 0; 1999 for I := 0 to Cell.Neighbors.Count - 1 do 2000 if (TCell(Cell.Neighbors[I]).Player <> Game.CurrentPlayer) and 2001 (TCell(Cell.Neighbors[I]).Player <> nil) then begin 2002 Inc(Result); 2003 end; 1923 2004 end; 1924 2005 … … 2055 2136 end; 2056 2137 2057 function TGame.AttackProbability(AttackCount, DefendCount , Depth: Integer): Double;2138 function TGame.AttackProbability(AttackCount, DefendCount: Integer): Double; 2058 2139 var 2059 2140 OA, OD: Integer; 2141 Len: Integer; 2142 I: Integer; 2060 2143 begin 2061 2144 if AttackCount = 0 then begin 2062 2145 Result := 0; 2063 2146 Exit; 2147 end; 2148 if DefendCount = 0 then begin 2149 Result := 1; 2150 Exit; 2151 end; 2152 2153 // Enlarge probability cache table on demand 2154 if Length(ProbabilityMatrix) < AttackCount then begin 2155 SetLength(ProbabilityMatrix, AttackCount); 2156 end; 2157 if Length(ProbabilityMatrix[AttackCount - 1]) < DefendCount then begin 2158 Len := Length(ProbabilityMatrix[AttackCount - 1]); 2159 SetLength(ProbabilityMatrix[AttackCount - 1], DefendCount); 2160 for I := Len to Length(ProbabilityMatrix[AttackCount - 1]) - 1 do 2161 ProbabilityMatrix[AttackCount - 1][I] := -1; 2162 end; 2163 2164 if ProbabilityMatrix[AttackCount - 1, DefendCount - 1] <> -1 then begin 2165 // Use cached value 2166 Result := ProbabilityMatrix[AttackCount - 1, DefendCount - 1]; 2167 Exit; 2064 2168 end else Result := 1; 2065 if DefendCount = 0 then Exit;2066 // TODO: Limiting depth is not solving problem with probability of high near2067 // numbers like 96 vs. 92. Complexity of calculation should be simplified2068 // in different way2069 if Depth > 10 then Exit;2070 2169 2071 2170 OA := Min(AttackCount, 3); … … 2073 2172 2074 2173 if (OA = 1) and (OD = 1) then 2075 Result := 0.4167 * AttackProbability(AttackCount, DefendCount - 1 , Depth + 1) +2076 0.5833 * AttackProbability(AttackCount - 1, DefendCount , Depth + 1)2174 Result := 0.4167 * AttackProbability(AttackCount, DefendCount - 1) + 2175 0.5833 * AttackProbability(AttackCount - 1, DefendCount) 2077 2176 else if (OA = 2) and (OD = 1) then 2078 Result := 0.5787 * AttackProbability(AttackCount, DefendCount - 1 , Depth + 1) +2079 0.4213 * AttackProbability(AttackCount - 1, DefendCount , Depth + 1)2177 Result := 0.5787 * AttackProbability(AttackCount, DefendCount - 1) + 2178 0.4213 * AttackProbability(AttackCount - 1, DefendCount) 2080 2179 else if (OA = 3) and (OD = 1) then 2081 Result := 0.6597 * AttackProbability(AttackCount, DefendCount - 1 , Depth + 1) +2082 0.3403 * AttackProbability(AttackCount - 1, DefendCount , Depth + 1)2180 Result := 0.6597 * AttackProbability(AttackCount, DefendCount - 1) + 2181 0.3403 * AttackProbability(AttackCount - 1, DefendCount) 2083 2182 else if (OA = 1) and (OD = 2) then 2084 Result := 0.2546 * AttackProbability(AttackCount, DefendCount - 1 , Depth + 1) +2085 0.7454 * AttackProbability(AttackCount - 1, DefendCount , Depth + 1)2183 Result := 0.2546 * AttackProbability(AttackCount, DefendCount - 1) + 2184 0.7454 * AttackProbability(AttackCount - 1, DefendCount) 2086 2185 else if (OA = 2) and (OD = 2) then 2087 Result := 0.2276 * AttackProbability(AttackCount, DefendCount - 2 , Depth + 1) +2088 0.4483 * AttackProbability(AttackCount - 2, DefendCount , Depth + 1) +2089 0.3241 * AttackProbability(AttackCount - 1, DefendCount - 1 , Depth + 1)2186 Result := 0.2276 * AttackProbability(AttackCount, DefendCount - 2) + 2187 0.4483 * AttackProbability(AttackCount - 2, DefendCount) + 2188 0.3241 * AttackProbability(AttackCount - 1, DefendCount - 1) 2090 2189 else if (OA = 3) and (OD = 2) then 2091 Result := 0.3717 * AttackProbability(AttackCount, DefendCount - 2, Depth + 1) + 2092 0.2926 * AttackProbability(AttackCount - 2, DefendCount, Depth + 1) + 2093 0.3358 * AttackProbability(AttackCount - 1, DefendCount - 1, Depth + 1); 2190 Result := 0.3717 * AttackProbability(AttackCount, DefendCount - 2) + 2191 0.2926 * AttackProbability(AttackCount - 2, DefendCount) + 2192 0.3358 * AttackProbability(AttackCount - 1, DefendCount - 1); 2193 ProbabilityMatrix[AttackCount - 1, DefendCount - 1] := Result; 2094 2194 end; 2095 2195
Note:
See TracChangeset
for help on using the changeset viewer.