I created this game inspired by this problem: https://www.codechef.com/ZCOPRAC/problems/ZCO14001
The problem needs you create a machine that can lift boxes and drop them in a new column. Then, when the problem asks you to, you have to print how many boxes are in every column.
I tried to improvise it and make it as as interesting and interactive as possible, but it's a bit too long, and also might contain bugs. How do I make it shorter?
It provides you a controller with tkinter buttons.
Here's the code:
from os import system
from tkinter import *
cls = lambda: system('cls')
class VideoGame:
def __init__(self, rows, columns, stacks):
self.stacks = stacks
self.rows = rows
self.columns = columns
self.cur_column = 0
self.box_in_hand = False
self.commands = {'1': self.move_left, '2': self.move_right,
'3': self.pick_up_box, '4': self.drop_box,
'5': self.add_row, '6': self.add_column,
'7': self.del_row, '8': self.del_column,
'9': self.fill_all, '10': self.remove_all
}
def command_parser(self, command):
cls()
self.commands[command]()
self.print()
def move_left(self):
if self.cur_column < 0:
print(f'\nNo place to move left\n')
return
self.cur_column -= 1
def move_right(self):
if self.cur_column >= self.rows:
print(f'\nNo place to move right\n')
return
self.cur_column += 1
def pick_up_box(self):
if self.box_in_hand:
print('\nAlready have a box in hand\n')
return
if self.cur_column == -1:
self.add_box()
return
if self.cur_column >= self.rows:
print('\nCan\'t pick up box from ()\n')
return
if self.stacks[self.cur_column] == 0:
print(f'\nNo box to pick up in row {self.cur_column + 1}\n')
return
self.stacks[self.cur_column] -= 1
self.box_in_hand = True
def drop_box(self):
if not self.box_in_hand:
print('\nDon\'t have a box in hand\n')
return
if self.cur_column == self.rows:
self.remove_box()
return
if self.cur_column < 0:
print('\nCan\'t drop box to {}\n')
return
if self.stacks[self.cur_column] == self.columns:
print(f'\nMax stack reached in row {self.cur_column + 1}\n')
return
self.stacks[self.cur_column] += 1
self.box_in_hand = False
def print(self):
print()
s1 = list('--') + list('--' * self.rows) + list('-')
s2 = list(' ') + list(' ' * self.rows) + list(' ' * 3)
s1[self.cur_column * 2 + 2] = 'O'
s2[self.cur_column * 2 + 2] = 'C'
if self.box_in_hand:
s2[self.cur_column * 2 + 3] = '['
s2[self.cur_column * 2 + 4] = ']'
print(''.join(s1))
print(''.join(s2))
print()
for i in range(self.columns, 0, -1):
print(end=' ')
for j in range(self.rows):
if self.stacks[j] >= i:
print('[]', end='')
else:
print(' ', end='')
print()
print('{}' + ' ' * self.rows + '()')
print()
def add_column(self):
self.columns += 1
def add_row(self):
self.rows += 1
self.stacks.append(0)
def del_row(self):
self.rows = max(0, self.rows - 1)
self.stacks = self.stacks[:-1]
self.cur_column = min(self.rows, self.cur_column)
def del_column(self):
self.columns = max(0, self.columns - 1)
self.stacks = [min(i, self.columns) for i in self.stacks]
def add_box(self):
self.box_in_hand = True
def remove_box(self):
self.box_in_hand = False
def fill_all(self):
self.stacks = [self.columns] * self.rows
def remove_all(self):
self.stacks = [0] * self.rows
def parser(arr):
return (list(map(lambda x: max(int(min(int(x), r)), 0), arr)) + [0] * r)[:r]
print('{} - Pick up box to create box\n'
'() - Drop box to delete box\n')
while True:
tk = Tk()
r = int(input('Enter number of rows: '))
c = int(input('Enter number of columns: '))
s = parser(input(f'Enter {r} spaced integers all less than or equal to {c}: ').split())
cls()
game = VideoGame(r, c, s)
game.print()
Button(tk, text='Enter Command', width=20, command=None).grid(row=0, column=0, columnspan=2)
Button(tk, text='Move Left', width=10, command=lambda: game.command_parser('1')).grid(row=2, column=0)
Button(tk, text='Move Right', width=10, command=lambda: game.command_parser('2')).grid(row=2, column=1)
Button(tk, text='Pick Box', width=10, command=lambda: game.command_parser('3')).grid(row=3, column=0)
Button(tk, text='Drop Box', width=10, command=lambda: game.command_parser('4')).grid(row=3, column=1)
Button(tk, text='Add Row', width=10, command=lambda: game.command_parser('5')).grid(row=4, column=0)
Button(tk, text='Add Column', width=10, command=lambda: game.command_parser('6')).grid(row=4, column=1)
Button(tk, text='Del Row', width=10, command=lambda: game.command_parser('7')).grid(row=5, column=0)
Button(tk, text='Del Column', width=10, command=lambda: game.command_parser('8')).grid(row=5, column=1)
Button(tk, text='Fill All', width=10, command=lambda: game.command_parser('9')).grid(row=6, column=0)
Button(tk, text='Remove All', width=10, command=lambda: game.command_parser('10')).grid(row=6, column=1)
Button(tk, text='Row Size', width=10, command=lambda: print('Number of rows =', game.rows)).grid(row=7, column=0)
Button(tk, text='Column Size', width=10, command=lambda: print('Number of columns =',game.columns)).grid(row=7, column=1)
Button(tk, text='Quit', width=5, command=lambda: tk.destroy()).grid(row=8, column=0, columnspan=2)
tk.mainloop()
cls()
How do I make my code shorter and easier to read?
Also, tips for making the code more interactive are welcome!
Thank you for your help!