Contract con_checkers_v1


Contract Code


  
1 # con_checkers_v1
2
3 NUM_ROWS = NUM_COLS = 8
4 NUM_SQUARES = NUM_ROWS * NUM_COLS
5 INITIAL_BOARD = ' b b b bb b b b b b b b w w w w w w w ww w w w '
6
7 assert len(INITIAL_BOARD) == NUM_SQUARES, 'Invalid initial board.'
8
9
10 def coords_to_index(x: int, y: int) -> int:
11 assert valid_coords(x, y), 'Invalid (x, y): ({}, {})'.format(x, y)
12 return x * NUM_ROWS + y
13
14
15 def index_to_coords(index: int) -> tuple:
16 assert valid_index(index), 'Invalid index: {}'.format(index)
17 x = index // NUM_ROWS
18 y = index % NUM_ROWS
19 return (x, y)
20
21
22 def valid_index(index: int) -> bool:
23 return index >= 0 and index < NUM_SQUARES
24
25 def valid_coords(x: int, y: int) -> bool:
26 return x >= 0 and x < NUM_ROWS and y >= 0 and y < NUM_COLS
27
28
29 MOVE_VECTORS = {
30 'b': [(1, 1), (1, -1)],
31 'w': [(-1, 1), (-1, -1)],
32 'B': [(-1, -1), (-1, 1), (1, -1), (1, 1)],
33 'W': [(-1, -1), (-1, 1), (1, -1), (1, 1)],
34 }
35
36 JUMP_VECTORS = {
37 'b': [(2, 2), (2, -2)],
38 'w': [(-2, 2), (-2, -2)],
39 'B': [(-2, -2), (-2, 2), (2, -2), (2, 2)],
40 'W': [(-2, -2), (-2, 2), (2, -2), (2, 2)],
41 }
42
43 OPPOSING = {
44 'b': 'w',
45 'B': 'w',
46 'w': 'b',
47 'W': 'b'
48 }
49
50 INITIAL_STATE = {
51 'current_player': 'b',
52 'board': str(INITIAL_BOARD),
53 'creator_team': 'b',
54 'opponent_team': 'w',
55 }
56
57
58 @export
59 def get_initial_state(x: str = None) -> dict:
60 return INITIAL_STATE
61
62
63 def opposing_team(team: str) -> str:
64 return OPPOSING[team.lower()]
65
66
67 def check_for_jumps(board: str, team: str) -> bool:
68 has_jumps = False
69 opponent = opposing_team(team)
70 for row in range(NUM_ROWS):
71 for col in range(NUM_COLS):
72 piece = board[row*NUM_ROWS+col]
73 if piece.lower() == team:
74 for valid_jump in JUMP_VECTORS[piece]:
75 next_x = row + valid_jump[0]
76 next_y = col + valid_jump[1]
77 if valid_coords(next_x, next_y) and board[coords_to_index(next_x, next_y)] == ' ':
78 # Check if opponent piece is in between
79 inbetween_x = row + valid_jump[0] // 2
80 inbetween_y = col + valid_jump[1] // 2
81 inbetween_index = coords_to_index(inbetween_x, inbetween_y)
82 if board[inbetween_index].lower() == opponent:
83 has_jumps = True
84 break
85 if has_jumps:
86 break
87 if has_jumps:
88 break
89 return has_jumps
90
91
92 def check_for_moves(board: str, team: str) -> bool:
93 has_moves = False
94 for row in range(NUM_ROWS):
95 for col in range(NUM_COLS):
96 piece = board[row*NUM_ROWS+col]
97 if piece.lower() == team:
98 for valid_move in MOVE_VECTORS[piece]:
99 next_x = row + valid_move[0]
100 next_y = col + valid_move[1]
101 if valid_coords(next_x, next_y) and board[coords_to_index(next_x, next_y)] == ' ':
102 # Check if opponent piece is in between
103 has_moves = True
104 break
105 if has_moves:
106 break
107 if has_moves:
108 break
109 return has_moves
110
111
112 @export
113 def force_end_round(state: dict, metadata: dict):
114 if state.get('winner') is None:
115 state['stalemate'] = True
116
117
118 @export
119 def move(caller: str, team: str, payload: dict, state: dict, metadata: dict):
120
121 x1=payload['x1']
122 y1=payload['y1']
123 x2=payload['x2']
124 y2=payload['y2']
125
126 board = list(state['board'])
127 curr_x = x1
128 curr_y = y1
129 curr_index = coords_to_index(x1, y1)
130 curr_piece = board[curr_index]
131 assert state['current_player'] == team, 'It is not your turn to move.'
132 assert curr_piece.lower() == team, 'This is not your piece to move.'
133 opponent = opposing_team(team)
134 valid_moves = MOVE_VECTORS[curr_piece]
135 valid_jumps = JUMP_VECTORS[curr_piece]
136 for i in range(len(x2)):
137 next_x = x2[i]
138 next_y = y2[i]
139 next_vector = (next_x - curr_x, next_y - curr_y)
140 next_index = coords_to_index(next_x, next_y)
141 if next_vector in valid_jumps and board[next_index] == ' ':
142 # Check there is an opposing piece
143 inbetween_x = curr_x + next_vector[0] // 2
144 inbetween_y = curr_y + next_vector[1] // 2
145 inbetween_index = coords_to_index(inbetween_x, inbetween_y)
146 assert board[inbetween_index].lower() == opponent, 'You cannot jump this square.'
147 board[inbetween_index] = ' '
148 board[curr_index] = ' '
149 board[next_index] = curr_piece
150 elif next_vector in valid_moves and board[next_index] == ' ':
151 # Check for jumps
152 assert not check_for_jumps(board, team), 'Must perform jump.'
153 # Simple move
154 board[next_index] = curr_piece
155 board[curr_index] = ' '
156 else:
157 assert False, 'Invalid move.'
158
159 # Check for kings
160 if team == 'b' and next_x == NUM_ROWS - 1:
161 if curr_piece == curr_piece.lower():
162 assert i == len(x2) -1, 'Cannot make a move after promoting to a king.'
163 board[next_index] = board[next_index].upper()
164 elif team == 'w' and next_x == 0:
165 if curr_piece == curr_piece.lower():
166 assert i == len(x2) -1, 'Cannot make a move after promoting to a king.'
167 board[next_index] = board[next_index].upper()
168 curr_x = next_x
169 curr_y = next_y
170 curr_index = next_index
171
172 opponent_has_jumps = check_for_jumps(board, opponent)
173 opponent_has_moves = check_for_moves(board, opponent)
174
175 board = ''.join(board)
176 state['current_player'] = opponent
177 state['board'] = board
178
179 if not opponent_has_jumps and not opponent_has_moves:
180 state['winner'] = team
181
182

Byte Code

e300000000000000000000000008000000400000007360010000640004005a005a016500650114005a0264015a0365046503830165026b027328740564028301820165066506650664039c036404640584045a076506650864069c026407640884045a096506650a64069c026409640a84045a0b65066506650a64039c03640b640c84045a0c642764296702642b642e6702643164336435643667046439643b643d643e6704640e9c045a0d643f644167026443644667026449644b644d644e670464516453645564566704640e9c045a0e641064106411641164129c045a0f64116510650383016411641064139c045a1165126414830164576510651364169c0264176418840583015a146510651064199c02641a641b84045a1565106510650a641c9c03641d641e84045a1665106510650a641c9c03641f642084045a176512641483016513651364219c0264226423840483015a186512641483016510651065136513651364249c0564256426840483015a19641553002958e9080000007a40206220622062206262206220622062202062206220622062202020202020202020202020202020207720772077207720207720772077207777207720772077207a16496e76616c696420696e697469616c20626f6172642e2903da0178da0179da0672657475726e630200000000000000020000000400000043000000732600000074007c007c018302731a740164016a027c007c018302830182017c00740314007c011700530029024e7a18496e76616c69642028782c2079293a20287b7d2c207b7d292904da0e5f5f76616c69645f636f6f726473da0e417373657274696f6e4572726f72da06666f726d6174da084e554d5f524f5753290272020000007203000000a9007209000000da00da115f5f636f6f7264735f746f5f696e64657808000000730400000000011a01720b0000002902da05696e6465787204000000630100000000000000030000000300000043000000732e00000074007c0083017316740164016a027c008301830182017c0074031a007d017c00740316007d027c017c026602530029024e7a11496e76616c696420696e6465783a207b7d2904da0d5f5f76616c69645f696e6465787206000000720700000072080000002903720c0000007202000000720300000072090000007209000000720a000000da115f5f696e6465785f746f5f636f6f7264730d00000073080000000001160108010801720e00000063010000000000000001000000020000004300000073100000007c0064016b056f0e7c0074006b00530029024ee9000000002901da0b4e554d5f535155415245532901720c00000072090000007209000000720a000000720d0000001400000073020000000001720d00000063020000000000000002000000020000004300000073200000007c0064016b056f1e7c0074006b006f1e7c0164016b056f1e7c0174016b00530029024e720f00000029027208000000da084e554d5f434f4c5329027202000000720300000072090000007209000000720a000000720500000018000000730200000000017205000000e9010000002904da0162da0177da0142da0157e90200000072140000007213000000290472130000007215000000721400000072160000002904da0e63757272656e745f706c61796572da05626f617264da0c63726561746f725f7465616dda0d6f70706f6e656e745f7465616dda0f636f6e5f636865636b6572735f76314e29027202000000720400000063010000000000000001000000010000004300000073040000007400530029014e2901da0d494e495449414c5f53544154452901720200000072090000007209000000720a000000da116765745f696e697469616c5f73746174652500000073020000000002721e0000002902da047465616d7204000000630100000000000000010000000200000043000000730c00000074007c006a0183001900530029014e2902da084f50504f53494e47da056c6f7765722901721f00000072090000007209000000720a000000da0f5f5f6f70706f73696e675f7465616d2a00000073020000000001722200000029037219000000721f00000072040000006302000000000000000d000000070000004300000073e200000064017d0274007c0183017d0378d074017402830144005dc47d0478b874017403830144005dac7d057c007c04740214007c05170019007d067c066a0483007c016b0272ca788474057c06190044005d787d077c047c076402190017007d087c057c076403190017007d0974067c087c098302724e7c0074077c087c098302190064046b02724e7c047c076402190064051a0017007d0a7c057c076403190064051a0017007d0b74077c0a7c0b83027d0c7c007c0c19006a0483007c036b02724e64067d025000714e57007c0272245000712457007c0272165000711657007c02530029074e46720f0000007212000000fa012072170000005429087222000000da0572616e6765720800000072110000007221000000da0c4a554d505f564543544f52537205000000720b000000290d7219000000721f000000da096861735f6a756d7073da086f70706f6e656e74da03726f77da03636f6cda057069656365da0a76616c69645f6a756d70da066e6578745f78da066e6578745f79da0b696e6265747765656e5f78da0b696e6265747765656e5f79da0f696e6265747765656e5f696e64657872090000007209000000720a000000da115f5f636865636b5f666f725f6a756d70732e000000732e0000000001040108010e010e0110010c010e010c010c010c01100110011001040106011001040106010401060104010601723100000063020000000000000009000000070000004300000073a000000064017d02789674007401830144005d8a7d03787e74007402830144005d727d047c007c03740114007c04170019007d057c056a0383007c016b027288784a74047c05190044005d3e7d067c037c066402190017007d077c047c066403190017007d0874057c077c08830272467c0074067c077c088302190064046b02724664057d025000714657007c02721c5000711c57007c02720e5000710e57007c02530029064e46720f000000721200000072230000005429077224000000720800000072110000007221000000da0c4d4f56455f564543544f52537205000000720b00000029097219000000721f000000da096861735f6d6f76657372280000007229000000722a000000da0a76616c69645f6d6f7665722c000000722d00000072090000007209000000720a000000da115f5f636865636b5f666f725f6d6f766573480000007322000000000104010e010e0110010c010e010c010c010c01100104010601040106010401060172350000002902da057374617465da086d65746164617461630200000000000000020000000300000043000000731a0000007c006a006401830164006b08721664027c0064033c006400530029044eda0677696e6e657254da097374616c656d6174652901da0367657429027236000000723700000072090000007209000000720a000000da0f666f7263655f656e645f726f756e645c000000730400000000020e01723b0000002905da0663616c6c6572721f000000da077061796c6f6164723600000072370000006305000000000000001b000000040000004300000073800200007c02640119007d057c02640219007d067c02640319007d077c02640419007d0874007c036405190083017d097c057d0a7c067d0b74017c057c0683027d0c7c097c0c19007d0d7c03640619007c016b02735a74026407830182017c0d6a0383007c016b02736e740264088301820174047c0183017d0e74057c0d19007d0f74067c0d19007d10900178ac740774087c0783018301440090015d9a7d117c077c1119007d127c087c1119007d137c127c0a18007c137c0b180066027d1474017c127c1383027d157c147c106b066fd87c097c15190064096b029001723a7c0a7c14640a1900640b1a0017007d167c0b7c14640c1900640b1a0017007d1774017c167c1783027d187c097c1819006a0383007c0e6b02900173207402640d8301820164097c097c183c0064097c097c0c3c007c0d7c097c153c006e4e7c147c0f6b069001727a7c097c15190064096b029001727a74097c097c0183020c00900173687402640e830182017c0d7c097c153c0064097c097c0c3c006e0e640f9001738874026410830182017c0164116b02900172da7c12740a640c18006b02900172da7c0d7c0d6a0383006b02900272267c1174087c078301640c18006b02900173c874026412830182017c097c1519006a0b83007c097c153c006e4c7c0164136b02900272267c12640a6b02900272267c0d7c0d6a0383006b02900272267c1174087c078301640c18006b029002731674026412830182017c097c1519006a0b83007c097c153c007c127d0a7c137d0b7c157d0c7196570074097c097c0e83027d19740c7c097c0e83027d1a64146a0d7c0983017d097c0e7c0364063c007c097c0364053c007c190c009002727c7c1a0c009002727c7c017c0364153c006400530029164eda027831da027931da027832da027932721900000072180000007a1c4974206973206e6f7420796f7572207475726e20746f206d6f76652e7a1f54686973206973206e6f7420796f757220706965636520746f206d6f76652e7223000000720f000000721700000072120000007a1c596f752063616e6e6f74206a756d702074686973207371756172652e7a124d75737420706572666f726d206a756d702e467a0d496e76616c6964206d6f76652e72130000007a2d43616e6e6f74206d616b652061206d6f76652061667465722070726f6d6f74696e6720746f2061206b696e672e7214000000720a0000007238000000290eda046c697374720b000000720600000072210000007222000000723200000072250000007224000000da036c656e72310000007208000000da0575707065727235000000da046a6f696e291b723c000000721f000000723d00000072360000007237000000723e000000723f000000724000000072410000007219000000da06637572725f78da06637572725f79da0a637572725f696e646578da0a637572725f70696563657227000000da0b76616c69645f6d6f766573da0b76616c69645f6a756d7073da0169722c000000722d000000da0b6e6578745f766563746f72da0a6e6578745f696e646578722e000000722f0000007230000000da126f70706f6e656e745f6861735f6a756d7073da126f70706f6e656e745f6861735f6d6f76657372090000007209000000720a000000da046d6f766562000000736a000000000208010801080108010c01040104010a0108011401140108010801080116010801080110010a011601100110010a010a011001080108010a011801160108010a020e0118010e0108011201120114010e010801120110010401040108010a010a010a010801080110017251000000290272120000007212000000e9ffffffff29027212000000725200000072520000002902725200000072120000007252000000725200000029027252000000725200000072520000007252000000290272520000007252000000725200000029027252000000721200000072520000002902721200000072520000002902721200000072120000007252000000725200000029027252000000725200000072520000002902725200000072120000007252000000290272120000007252000000290272120000007212000000290272170000007217000000e9feffffff2902721700000072530000007253000000290272530000007217000000725300000072530000002902725300000072530000007253000000725300000029027253000000725300000072530000002902725300000072170000007253000000290272170000007253000000290272170000007217000000725300000072530000002902725300000072530000007253000000290272530000007217000000725300000029027217000000725300000029027217000000721700000029014e291a720800000072110000007210000000da0d494e495449414c5f424f41524472430000007206000000da03696e74720b000000da057475706c65720e000000da04626f6f6c720d0000007205000000723200000072250000007220000000da03737472721d000000da085f5f6578706f7274da0464696374721e000000722200000072310000007235000000723b0000007251000000720900000072090000007209000000720a000000da083c6d6f64756c653e01000000732e000000080108020401140312051007100412040c011a010c011a010e0108010a03060114041004121a1214060112050601