Created
July 1, 2017 14:01
-
-
Save SpaceVoyager/75aff54c291fee7e6b6d8711304d633c to your computer and use it in GitHub Desktop.
rabbitrobber.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ui | |
import random | |
import numpy as np | |
rabbit_size = 50 | |
v = ui.View(background_color=('#bcdeff')) | |
board = ui.View() | |
v.add_subview(board) | |
v.present('full_screen', hide_title_bar=False , orientations=['landscape']) | |
board.frame = (v.width-v.height + rabbit_size/2, rabbit_size/2 , v.height - rabbit_size, v.height - rabbit_size) | |
board.border_width = 10 | |
board.border_color = ('black') | |
board.background_color = ('#ffffff') | |
rows = 8 | |
cols = 8 | |
blocks = {} | |
different_blocks = ['O', 'B', 'W'] | |
blocks_probs = [0.8, 0.1, 0.1] | |
money_balance = 0 | |
bank_money_robbed_once = 10000 | |
money_taken_once = -20000 | |
score_label = ui.Label() | |
score_label.text = 'Money Balance:' | |
score_label.width = 300 | |
score_label.x = 20 | |
score_label.y = 20 | |
score_label.font = ('Chalkduster', 26) | |
score_label.alignment = ui.ALIGN_LEFT | |
v.add_subview(score_label) | |
score_label2 = ui.Label() | |
score_label2.text = '$0' | |
score_label2.width = 300 | |
score_label2.text_color = .0, 0.8, .35 | |
score_label2.x = 20 | |
score_label2.y = 60 | |
score_label2.font = ('Chalkduster', 30) | |
score_label2.alignment = ui.ALIGN_LEFT | |
v.add_subview(score_label2) | |
manhattan_grid = np.chararray((rows, cols)) | |
manhattan_grid[:] = 'O' # fill up manhattan_grid with 'O', which means empty block | |
for r in range(rows): | |
for c in range(cols): | |
random_num = random.randint(1, 100) | |
image = ui.ImageView() | |
if random_num < 12: | |
image = ui.ImageView() | |
image.image = ui.Image('emj:Boar') | |
manhattan_grid[r,c] = 'W' | |
elif random_num < 24 and random_num > 11: | |
image = ui.ImageView() | |
image.image = ui.Image('emj:Bank') | |
manhattan_grid[r,c] = 'B' | |
else: | |
image.background_color = ('#838383') | |
image.width = board.height/cols | |
image.height = board.height/rows | |
image.border_color = ('black') | |
image.border_width = 5 | |
image.x = image.width*c | |
image.y = image.height*r | |
image.font = ('American Typewriter',60) | |
board.add_subview(image) | |
blocks[(r,c)] = image | |
def get_block_entity(r, c): | |
if r >= 0 and r < rows and c >= 0 and c < cols: | |
return manhattan_grid[r,c] | |
else: | |
return None | |
def find_entities(old_position, new_position): | |
(old_r, old_c) = old_position | |
(new_r, new_c) = new_position | |
nw_block_entity = get_block_entity(new_r - 1, new_c - 1) | |
ne_block_entity = get_block_entity(new_r - 1, new_c) | |
sw_block_entity = get_block_entity(new_r, new_c - 1) | |
if old_r == new_r: | |
return (nw_block_entity, sw_block_entity) | |
else: | |
return (ne_block_entity, nw_block_entity) | |
rabbit_buttons = [] | |
normal_rabbit_color = (1.0, .54, .78, 1.0) | |
ghost_rabbit_color = (1.0, .96, 1.0, 0.5) | |
trail_rabbit_color = (0.9, .96, 1.0, 1.0) | |
old_r = None | |
old_c = None | |
def rabbit_tapped(sender): | |
global old_c, old_r, money_balance | |
if sender.tint_color in [normal_rabbit_color, ghost_rabbit_color]: | |
for b in rabbit_buttons: | |
if b['rabbit'] == sender: | |
my_col_num = b['column_number'] | |
my_row_num = b['row_number'] | |
break | |
if sender.tint_color == ghost_rabbit_color: | |
blocks = find_entities((old_r, old_c), (my_row_num, my_col_num)) | |
for b in blocks: | |
if b == 'B': | |
money_balance += bank_money_robbed_once | |
if b == 'W': | |
money_balance += money_taken_once | |
score_label2.text = '$' + str(money_balance) | |
for b in rabbit_buttons: | |
if b['rabbit'].tint_color == normal_rabbit_color: | |
b['rabbit'].tint_color = trail_rabbit_color | |
sender.tint_color = normal_rabbit_color | |
for b in rabbit_buttons: | |
if b['rabbit'].tint_color == ghost_rabbit_color: | |
b['rabbit'].image = None | |
b['rabbit'].tint_color = (1,1,1,1) | |
if sender.tint_color == normal_rabbit_color: | |
old_c = my_col_num | |
old_r = my_row_num | |
for b in rabbit_buttons: | |
if b['row_number'] == my_row_num + 1 and b['column_number'] == my_col_num: | |
b['rabbit'].tint_color = ghost_rabbit_color | |
b['rabbit'].image = ui.Image('emj:Rabbit_Face') | |
if b['row_number'] == my_row_num and b['column_number'] == my_col_num + 1: | |
b['rabbit'].tint_color = ghost_rabbit_color | |
b['rabbit'].image = ui.Image('emj:Rabbit_Face') | |
def dp_solver(input_grid): | |
n_row = input_grid.shape[0] | |
n_col = input_grid.shape[1] | |
dp_table = np.zeros(shape=(n_row+1,n_col+1)) | |
# table that stores the choices made by the rabbit at each intersection | |
choices_table = np.chararray(shape=(n_row+1,n_col+1)) | |
choices_table[0,0] = 'O' | |
# When the rabbit tries to figure out the best way to go to | |
# the intersection at r row and c column, it needs to know | |
# what kinds of entities lie long the streets. | |
# This function finds the entities in the NW, NE and SW blocks | |
# and returns them in a tuple (NW entity, NE entity, SW entity) | |
def find_entities(r, c): | |
nw_block_entity = get_block_entity(r - 1, c - 1) | |
ne_block_entity = get_block_entity(r - 1, c) | |
sw_block_entity = get_block_entity(r, c - 1) | |
return (nw_block_entity, ne_block_entity, sw_block_entity) | |
# filling up the first row of dp_table | |
for c in range(1, n_col+1): | |
(nw_block_entity, ne_block_entity, sw_block_entity) = find_entities(0, c) | |
if sw_block_entity == 'B': | |
dp_table[0,c] = dp_table[0,c-1] + bank_money_robbed_once | |
elif sw_block_entity == 'W': | |
dp_table[0,c] = dp_table[0,c-1] + money_taken_once | |
else: | |
dp_table[0,c] = dp_table[0,c-1] | |
choices_table[0,c] = 'W' | |
# filling up the first column of dp_table | |
for r in range(1, n_row+1): | |
(nw_block_entity, ne_block_entity, sw_block_entity) = find_entities(r, 0) | |
if ne_block_entity == 'B': | |
dp_table[r,0] = dp_table[r-1,0] + bank_money_robbed_once | |
elif ne_block_entity == 'W': | |
dp_table[r,0] = dp_table[r-1,0] + money_balance | |
else: | |
dp_table[r,0] = dp_table[r-1,0] | |
choices_table[r,0] = 'N' | |
for r in range(1, n_row+1): | |
for c in range(1, n_col+1): | |
(nw_block_entity, ne_block_entity, sw_block_entity) = find_entities(r, c) | |
# find money stored at intersection above | |
north_intersection_money = dp_table[r-1, c] | |
option1_money = north_intersection_money | |
if nw_block_entity == 'B': | |
option1_money += bank_money_robbed_once | |
if nw_block_entity == 'W': | |
option1_money += money_taken_once | |
if ne_block_entity == 'B': | |
option1_money += bank_money_robbed_once | |
if ne_block_entity == 'W': | |
option1_money += money_taken_once | |
# find money stored at intersection to the left | |
west_intersection_money = dp_table[r, c-1] | |
option2_money = west_intersection_money | |
if nw_block_entity == 'B': | |
option2_money += bank_money_robbed_once | |
if nw_block_entity == 'W': | |
option2_money += money_taken_once | |
if sw_block_entity == 'B': | |
option2_money += bank_money_robbed_once | |
if sw_block_entity == 'W': | |
option2_money += money_taken_once | |
if option1_money > option2_money: | |
dp_table[r,c] = option1_money | |
choices_table[r,c] = 'N' | |
else: | |
dp_table[r,c] = option2_money | |
choices_table[r,c] = 'W' | |
# we are going to trace the best solution from the exit point (bottom right corner) | |
# back to the starting point (upper left corner) | |
best_path = [] | |
r = n_row | |
c = n_col | |
this_choice = choices_table[r,c] | |
while (this_choice != 'O'): | |
if this_choice == 'W': | |
best_path.append('E') | |
c -= 1 | |
else: | |
best_path.append('S') | |
r -= 1 | |
this_choice = choices_table[r,c] | |
best_path.reverse() | |
return (dp_table[n_row, n_col], best_path) | |
for r in range(rows + 1): | |
for c in range(cols + 1): | |
test_rabbit_button = ui.Button() | |
if r == 0 and c == 0: | |
test_rabbit_button.image = ui.Image('emj:Rabbit_Face') | |
print test_rabbit_button.tint_color | |
test_rabbit_button.tint_color = normal_rabbit_color | |
test_rabbit_button.x = -18 + v.width-v.height + rabbit_size/2 + c*float(board.width-10)/cols | |
test_rabbit_button.y = -5 + r*float(board.height - 3)/rows | |
test_rabbit_button.width = rabbit_size | |
test_rabbit_button.height = rabbit_size | |
test_rabbit_button.action = rabbit_tapped | |
v.add_subview(test_rabbit_button) | |
rabbit_buttons.append({'rabbit' : test_rabbit_button, 'row_number' : r, 'column_number' : c}) | |
def solve_button_pressed(sender): | |
print dp_solver(manhattan_grid) | |
solver_button = ui.Button(title='Best Solution') | |
solver_button.action = solve_button_pressed | |
solver_button.x = 50 | |
solver_button.y = 200 | |
solver_button.width = 200 | |
solver_button.height = 50 | |
solver_button.border_width = 1 | |
solver_button.corner_radius = 5 | |
v.add_subview(solver_button) | |
def new_game(): | |
global money_balance, manhattan_grid | |
money_balance = 0 | |
score_label2.text = '$' + str(money_balance) | |
manhattan_grid[:] = 'O' # fill up manhattan_grid with 'O', which means empty block | |
random_blocks = np.random.choice(different_blocks, rows*cols, p=blocks_probs) | |
print random_blocks | |
index = 0 | |
for r in range(rows): | |
for c in range(cols): | |
image = blocks[(r,c)] | |
image.image = None | |
picked_block = random_blocks[index] | |
index += 1 | |
if picked_block == 'W': | |
image.image = ui.Image('emj:Boar') | |
manhattan_grid[r,c] = 'W' | |
elif picked_block == 'B': | |
image.image = ui.Image('emj:Bank') | |
manhattan_grid[r,c] = 'B' | |
else: | |
image.background_color = ('#838383') | |
for b in rabbit_buttons: | |
b['rabbit'].image = None | |
b['rabbit'].tint_color = (0.0, 0.47843137254901963, 1.0, 1.0) | |
rabbit_buttons[0]['rabbit'].image = ui.Image('emj:Rabbit_Face') | |
rabbit_buttons[0]['rabbit'].tint_color = normal_rabbit_color | |
def newgame_button_pressed(sender): | |
new_game() | |
newgame_button = ui.Button(title='New Game') | |
newgame_button.action = newgame_button_pressed | |
newgame_button.x = 50 | |
newgame_button.y = 300 | |
newgame_button.width = 200 | |
newgame_button.height = 50 | |
newgame_button.border_width = 1 | |
newgame_button.corner_radius = 5 | |
v.add_subview(newgame_button) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment