-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathFile_handler.py
212 lines (179 loc) · 6.27 KB
/
File_handler.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import random
import UI_Handler as UI
import Settings.PROJECT_SETTINGS as settings
CONSOLE_APPLICATION = settings.isConsoleApplication()
FENlookup = {
"r": "♖",
"n": "♘",
"b": "♗",
"q": "♕",
"k": "♔",
"p": "♙",
"R": "♜",
"N": "♞",
"B": "♝",
"Q": "♛",
"K": "♚",
"P": "♟",
}
def load(gameType,fen=""):
# returns all variables needed by main to run the game
# colour -> the players colour in the game "White" or "Black"
# playerTurn -> boolean value
# TurnNumber -> is 1 unless the game is loaded from an already started game where it may be different
# board -> 2d array
# the parameter gameType holds all of the settings for the game and will be expanded in the future as gameConfig() grows
colour = None
playerTurn = None
board = None
castlingData = None
enPassant = None
if gameType == "new":
board,colour,playerTurn,castlingData,enPassant = boardSetup(giveRandomColour())
elif gameType == "old": # loading a previously played unfinished game
numOfGames,games,gameNames = gamesAvailable()
if numOfGames != 0:
UI.sleep(1)
board,colour,playerTurn,castlingData,enPassant = FENBoard(games[UI.generateMenu(gameNames)])
print("\nLoading game...")
UI.sleep(1)
elif gameType == "FEN":
if not CONSOLE_APPLICATION:
if validFEN(fen):
board,colour,playerTurn,castlingData,enPassant = FENBoard(fen)
else:
board,colour,playerTurn,castlingData,enPassant = FENBoard(getFEN())
return colour,playerTurn,board,castlingData,enPassant
def gameConfig(tutorial = False):
# returns the settings for the game as a string
if not CONSOLE_APPLICATION:
if tutorial:
return "FEN"
else:
return "new"
UI.sleep(1)
option = UI.generateMenu(["New Game","Load Game [" + str(gamesAvailable()[0]) + " available]"])
if option == 0:
UI.sleep(1)
option = UI.generateMenu(["New Game", "Load game from FEN"])
if option == 0:
return "new"
else:
return "FEN"
else:
return "old"
def boardSetup(playerColour):
# returns a 2d array
# flips the board depending on what pieces the player has
if playerColour == "WHITE":
data = FENBoard("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
return data[0],"WHITE",True,data[3],data[4]
else:
data = FENBoard("RNBKQBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbkqbnr b KQkq - 0 1")
return data[0],"BLACK",False,data[3],data[4]
def validFEN(fen):
fields = fen.split()
if len(fields) != 6:
return False # FEN must have exactly 6 parts
piece_placement, active_color, castling, en_passant, halfmove, fullmove = fields
# Check if the board has 8 rows
ranks = piece_placement.split('/')
if len(ranks) != 8:
return False
# Check if each rank adds up to 8 squares
for rank in ranks:
count = 0
for char in rank:
if char.isdigit():
count += int(char)
else:
count += 1
if count != 8:
return False
# Check if active color is 'w' or 'b'
if active_color not in ('w', 'b'):
return False
# Check castling rights (must be valid or '-')
valid_castling = set("KQkq-")
if any(c not in valid_castling for c in castling):
return False
# Check en passant target square (must be valid or '-')
valid_en_passant = [f"{c}{n}" for c in "abcdefgh" for n in "36"] + ["-"]
if en_passant not in valid_en_passant:
return False
# Check if halfmove and fullmove are numbers
if not (halfmove.isdigit() and fullmove.isdigit()):
return False
return True
def getFEN():
UI.sleep(2)
fen = ""
while not validFEN(fen):
UI.clear()
fen = input("Enter a valid FEN string in the space below\n\ninput: ")
return fen
def FENBoard(fenString):
allInfo = fenString.split(' ')
boardData = allInfo[0].split("/")
whosTurn = allInfo[1]
canCastle = allInfo[2]
enPassant = allInfo[3]
halfMoves = allInfo[4]
fullMoves = allInfo[5]
playerTurn = False
if whosTurn == "w":
whosTurn = "WHITE"
playerTurn = True
else:
whosTurn = "BLACK"
playerTurn = False
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
for i in range(len(boardData)):
actualIndex = 0
for j in range(len(boardData[i])):
if boardData[i][j] in ['1','2','3','4','5','6','7','8']:
numOfTimes = int(boardData[i][j])
for x in range(numOfTimes):
board[i][actualIndex + x] = ' '
actualIndex = actualIndex + numOfTimes - 1
else:
piece = FENlookup[boardData[i][j]]
board[i][actualIndex] = piece
actualIndex = actualIndex + 1
return board,whosTurn,playerTurn,canCastle,enPassant
def giveRandomColour():
if random.randint(0,1) == 0:
return "WHITE"
else:
return "BLACK"
def gamesAvailable():
# returns a string with either 'No games found' or 'N games found' where N is the number of games
# will show player how many games they have on going
saveFile = None
games = []
gameNames = []
numOfGames = 0
try:
saveFile = None
try:
saveFile = open(r"Data\SaveFile.txt","rt")
except:
saveFile = open(r"Data/SaveFile.txt","rt")
for game in saveFile:
numOfGames = numOfGames + 1
game = game.split(",")
games = games + [game[0]]
gameNames = gameNames + [game[1]]
saveFile.close()
except:
print("File doesnt exist")
if numOfGames == 0:
numOfGames = "No games"
return numOfGames,games,gameNames