-
Notifications
You must be signed in to change notification settings - Fork 0
/
GameManager_3.py
122 lines (96 loc) · 3.85 KB
/
GameManager_3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from Grid_3 import Grid
from ComputerAI_3 import ComputerAI
from PlayerAI_3 import PlayerAI
from Displayer_3 import Displayer
import time
import random
defaultInitialTiles = 2
defaultProbability = 0.9
actionDic = {
0: "UP",
1: "DOWN",
2: "LEFT",
3: "RIGHT",
None: "NONE" # For error logging
}
(PLAYER_TURN, COMPUTER_TURN) = (0, 1)
# Time Limit Before Losing
timeLimit = 0.2
allowance = 0.05
maxTime = timeLimit + allowance
class GameManager:
def __init__(self, size=4, playerAI=None, computerAI=None, displayer=None):
self.grid = Grid(size)
self.possibleNewTiles = [2, 4]
self.probability = defaultProbability
self.initTiles = defaultInitialTiles
self.over = False
# Initialize the AI players
self.computerAI = computerAI or ComputerAI()
self.playerAI = playerAI or PlayerAI()
self.displayer = displayer or Displayer()
def updateAlarm(self) -> None:
""" Checks if move exceeded the time limit and updates the alarm """
if time.process_time() - self.prevTime > maxTime:
self.over = True
self.prevTime = time.process_time()
def getNewTileValue(self) -> int:
""" Returns 2 with probability 0.95 and 4 with 0.05 """
return self.possibleNewTiles[random.random() > self.probability]
def insertRandomTiles(self, numTiles:int):
""" Insert numTiles number of random tiles. For initialization """
for i in range(numTiles):
tileValue = self.getNewTileValue()
cells = self.grid.getAvailableCells()
cell = random.choice(cells) if cells else None
self.grid.setCellValue(cell, tileValue)
def start(self) -> int:
""" Main method that handles running the game of 2048 """
# Initialize the game
self.insertRandomTiles(self.initTiles)
self.displayer.display(self.grid)
turn = PLAYER_TURN # Player AI Goes First
self.prevTime = time.process_time()
while self.grid.canMove() and not self.over:
# Copy to Ensure AI Cannot Change the Real Grid to Cheat
gridCopy = self.grid.clone()
move = None
if turn == PLAYER_TURN:
print("Player's Turn: ", end="")
move = self.playerAI.getMove(gridCopy)
print(actionDic[move])
# If move is valid, attempt to move the grid
if move != None and 0 <= move < 4:
if self.grid.canMove([move]):
self.grid.move(move)
else:
print("Invalid PlayerAI Move - Cannot move")
self.over = True
else:
print("Invalid PlayerAI Move - Invalid input")
self.over = True
else:
print("Computer's turn: ")
move = self.computerAI.getMove(gridCopy)
# Validate Move
if move and self.grid.canInsert(move):
self.grid.setCellValue(move, self.getNewTileValue())
else:
print("Invalid Computer AI Move")
self.over = True
# Comment out during heuristing optimizations to increase runtimes.
# Printing slows down computation time.
self.displayer.display(self.grid)
# Exceeding the Time Allotted for Any Turn Terminates the Game
self.updateAlarm()
turn = 1 - turn
return self.grid.getMaxTile()
def main():
playerAI = PlayerAI()
computerAI = ComputerAI()
displayer = Displayer()
gameManager = GameManager(4, playerAI, computerAI, displayer)
maxTile = gameManager.start()
print(maxTile)
if __name__ == '__main__':
main()