-
Notifications
You must be signed in to change notification settings - Fork 0
/
Carcassonne.py
110 lines (103 loc) · 5.63 KB
/
Carcassonne.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
"""
Carcassonne Game
Python Back-end
@author: Justin Divens
"""
import numpy as np
import pandas as pnd
# ----------------------------------------------------------------------
# Initial game setup. Creates board object and tile object
# ----------------------------------------------------------------------
def StartGame():
#Setup Board
start_append = pnd.DataFrame({'TILE_ID':'0','TILE_X':0,'TILE_Y':0,'TILE_CONFIG':'CCCFRFFFFFRF','PLAYER_ID':'START','MEEPLE':'0'}, index=[0])
board = pnd.DataFrame(columns=['TILE_ID','TILE_X','TILE_Y','TILE_CONFIG','PLAYER_ID','MEEPLE'])
board = board.append(start_append, ignore_index=True) #add starting tile
#Setup Tiles
tiles = pnd.read_csv('tiles_start.csv',header=0) #import csv starter file
tiles.insert(3,'STATUS',1) #insert status column in tiles dataframe
status = np.array(tiles['STATUS']) #create status array from tiles
status[0] = 0 #set status=0 for starting tile
tiles['STATUS'] = status #update status column of tiles dataframe
#Convert data to json
#DataFrame.to_json(path_or_buf=None, orient=None, date_format='epoch', double_precision=10, force_ascii=True, date_unit='ms', default_handler=None)
return(board, tiles)
# ----------------------------------------------------------------------
# Choose random tile from pile and mark tile as used
# ----------------------------------------------------------------------
def GetTile(tiles):
tiles_current = tiles.query('STATUS == 1') #grab tiles with status=1
#tiles_current = tiles[tiles['STATUS']==1] #grab tiles with status=1
tile_inhand = np.random.choice(tiles_current.index) #choose random tile
status = np.array(tiles['STATUS']) #create status array from tiles
status[tile_inhand] = 0 #set status=0 for randomly chosen tile
tiles['STATUS'] = status #update status column of tiles dataframe
#Convert data to json
#DataFrame.to_json(path_or_buf=None, orient=None, date_format='epoch', double_precision=10, force_ascii=True, date_unit='ms', default_handler=None)
return(tiles, tile_inhand)
# ----------------------------------------------------------------------
# Update game with player's turn choices
# ----------------------------------------------------------------------
def PlaceTile(tiles, tile_inhand, board, tileX, tileY, rotate, player, meeple):
#Create dataframe object of current placement to be appended to board
placement = pnd.DataFrame(columns=['TILE_ID','TILE_X','TILE_Y','TILE_CONFIG','PLAYER_ID','MEEPLE'], index=[0])
placement['TILE_ID'] = tile_inhand
placement['TILE_X'] = tileX
placement['TILE_Y'] = tileY
placement['PLAYER_ID'] = player
placement['MEEPLE'] = meeple
#Rotate tile algorithm
if rotate == '0':
new_config = tiles['TILE_CONFIG'][tile_inhand]
placement['TILE_CONFIG'] = new_config
elif rotate == '90':
new_config = tiles['TILE_CONFIG'][tile_inhand][9:12] + tiles['TILE_CONFIG'][tile_inhand][0:3] +\
tiles['TILE_CONFIG'][tile_inhand][3:6] + tiles['TILE_CONFIG'][tile_inhand][6:9]
placement['TILE_CONFIG'] = new_config
elif rotate == '180':
new_config = tiles['TILE_CONFIG'][tile_inhand][6:9] + tiles['TILE_CONFIG'][tile_inhand][9:12] + \
tiles['TILE_CONFIG'][tile_inhand][0:3] + tiles['TILE_CONFIG'][tile_inhand][3:6]
placement['TILE_CONFIG'] = new_config
elif rotate == '270':
new_config = tiles['TILE_CONFIG'][tile_inhand][3:6] + tiles['TILE_CONFIG'][tile_inhand][6:9] + \
tiles['TILE_CONFIG'][tile_inhand][9:12] + tiles['TILE_CONFIG'][tile_inhand][0:3]
placement['TILE_CONFIG'] = new_config
else:
error_msg = 'Invalid rotate'
return(error_msg)
#Check placement for invalid moves
tileX = float(tileX)
tileY = float(tileY)
check_center = board.query('TILE_X == @tileX & TILE_Y == @tileY')
check_top = board.query('TILE_X == @tileX & TILE_Y == (@tileY+1)')
check_right = board.query('TILE_X == (@tileX+1) & TILE_Y == @tileY')
check_bottom = board.query('TILE_X == @tileX & TILE_Y == (@tileY-1)')
check_left = board.query('TILE_X == (@tileX-1) & TILE_Y == @tileY')
#"""
print('center: ',str(check_center['TILE_CONFIG']))
print('top: ',str(check_top['TILE_CONFIG']))
print('right: ',str(check_right['TILE_CONFIG'])) #For troubleshooting
print('bottom: ',str(check_bottom['TILE_CONFIG']))
print('left: ',str(check_left['TILE_CONFIG']))
#"""
#Update board if all checks pass
if check_center.empty: #check if spot is already taken
if (check_top.empty and check_right.empty and check_bottom.empty and check_left.empty): #check if next to existing tile
error_msg = 'Not next to existing tile'
return(error_msg, board)
else:
if (check_top.empty or str(check_top['TILE_CONFIG'])[12]==new_config[1]) & \
(check_right.empty or str(check_right['TILE_CONFIG'])[15]==new_config[4]) & \
(check_bottom.empty or str(check_bottom['TILE_CONFIG'])[6]==new_config[7]) & \
(check_left.empty or str(check_left['TILE_CONFIG'])[9]==new_config[10]):
board = board.append(placement)
print(board)
#Convert data to json
#DataFrame.to_json(path_or_buf=None, orient=None, date_format='epoch', double_precision=10, force_ascii=True, date_unit='ms', default_handler=None)
return(board)
else:
error_msg = 'Tile features do not line up'
return(error_msg, board)
else:
error_msg = 'Spot already taken'
return(error_msg, board)