I am programming an Othello game in a GUI. I have begun working on the animations that flip certain tiles, which is here. My computer(s) will start choking when the when the amount of tiles on the board becomes larger. I do not know what to do to simplify this code or use less memory. (I can use an automove key I have enabled to finish the game at light speed, without the animations. That works fine.) Here is the definition I am using to flip the tiles.
def animateFlips(self, i):
self._canvas.delete(tkinter.ALL)
column_width = self._canvas.winfo_width()/Othello.COLUMNS
row_height = (self._canvas.winfo_height()-self._scoreBoard)/Othello.ROWS
newBoard = self._game.board
animatedTileCoords = []
color = ''
oppcolor = ''
if self._game.turn == 2:
color = 'black'
oppcolor = 'white'
elif self._game.turn == 1:
color = 'white'
oppcolor = 'black'
for x in range(Othello.COLUMNS):
for y in range(Othello.ROWS):
x1 = x * column_width
y1 = y * row_height
x2 = x1 + column_width
y2 = y1 + row_height
self._canvas.create_rectangle(x1,y1,x2,y2)
if self._game.board[x][y] == 1:
self._canvas.create_oval(x1,y1,x2,y2,fill='black')
elif self._game.board[x][y] == 2:
self._canvas.create_oval(x1,y1,x2,y2,fill='white')
elif self._game.board[x][y] == 3 or self._game.board[x][y] == 4:
animatedTileCoords.append([x,y])
for x, y in animatedTileCoords:
x1 = x * column_width
y1 = y * row_height
x2 = x1 + column_width
y2 = y1 + row_height
if i == 1:
self._canvas.create_oval(x1,y1,x2,y2,fill=oppcolor)
self._canvas.after(50, lambda: self.animateFlips(2))
elif i == 2:
self._canvas.create_oval(x1 + (column_width/4),y1,x1 + (3*column_width/4),y2,fill=oppcolor)
self._canvas.after(50, lambda: self.animateFlips(3))
elif i == 3:
self._canvas.create_oval(x1 + (column_width/2),y1,x1 + (column_width/2),y2,fill=oppcolor)
self._canvas.after(50, lambda: self.animateFlips(4))
elif i == 4:
self._canvas.create_oval(x1 + (column_width/4),y1,x1 + (3*column_width/4),y2,fill=color)
self._canvas.after(50, lambda: self.animateFlips(5))
elif i == 5:
self._canvas.create_oval(x1,y1,x2,y2,fill=color)
newBoard[x][y] = Othello.nextTurn(self._game.turn)
self._game = GameState(board = newBoard, turn = self._game.turn, skipped = 0)
self.displayMoves()
self.displayButtons()
self.displayInfo()
self.displayWinner(self.getWinner())
self._canvas.bind('<Configure>',self.draw_handler)
The simplest solution is to not delete and recreate the game pieces on each iteration. Draw them once, and then use the itemconfig method to alter the appearance of the game pieces.
Even better would be to create a GamePiece class so that each piece is represented by this class. Then, move the animation function inside the class. This will make your main logic much easier to understand.
Related
I just currently finished making the game 'snake' as a practice to learn how to program, as I am new to programming for about 3 months.
Although the game is completed and runs the way I intended, I want to try to simplify my code and reduce the amount of lines as much as possible, and possibly make the script tidier as the current majority of my codes are cluster in the while loop.
Until now I haven't touched upon class objects, and I want everything in the while loop to go into individual classes that get called out from the while loop to reduce the amount of lines in it.
off-topic: by reading through the script, how else can I improve it to be run more efficiently, including simplifying some code as I may have over-complicated it?
I looked up how class object is used from w3school and other programming tutorials, but I still don't fully understand it as it only shows examples in using print. I did play around and experimented with class object examples and attempted to call them without using print, but I lack the knowledge of how to use them properly.
from graphics import *
from threading import Timer
import keyboard, random, time
# configurations
width = 400
gridHeight = width
height = 470
timer = False
game = True
score = 0
bonus = 0
x = 70
y = 30
radius = 10
length = radius * 2
playerLength = 3
poisonLength = playerLength
i = 0
k = 0
pointRadius = 5
points = False
cherryPoints = False
key = "Right"
countDown = 0
# set coordinations
cX = 90
cY = 30
coordX = [10]
coordY = [10]
while coordX[len(coordX)-1] != width-10:
cX+=20
coordX.append(cX)
while coordY[len(coordY)-1] != 390:
cY+=20
coordY.append(cY)
randomX = random.choice(coordX)
randomY = random.choice(coordY)
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
# window set up
win = GraphWin("SNAKE", width, height, autoflush = False)
win.setBackground(color_rgb(15,15,15))
# grid
lineX = 20
while lineX < width:
gridX = Line(Point(lineX,0),Point(lineX,gridHeight))
gridX.setOutline(color_rgb(25,25,25))
gridX.draw(win)
lineX += 20
lineY = 20
while lineY <= gridHeight:
gridX = Line(Point(0,lineY),Point(width,lineY))
gridX.setOutline(color_rgb(25,25,25))
gridX.draw(win)
lineY += 20
# snake banner
UI = Rectangle(Point(0,400),Point(width,height))
UI.setFill(color_rgb(102,51,0))
UI.setOutline(color_rgb(102,51,0))
UI.draw(win)
snakeTitle = Text(Point(width/2,420),"SNAKE")
snakeTitle.setTextColor("green")
snakeTitle.setSize(20)
snakeTitle.draw(win)
scoreTitle = Text(Point(320,424),"SCORE")
scoreTitle.setTextColor("white")
scoreTitle.setSize(10)
scoreTitle.draw(win)
scoreUI = Text(Point(320,435),score)
scoreUI.setTextColor("white")
scoreUI.setSize(10)
scoreUI.draw(win)
# make player
player = {}
player[0] = Rectangle(Point(x-20-radius,y-radius), Point(x-20+radius, y+radius))
player[1] = Rectangle(Point(x-40-radius,y-radius), Point(x-40+radius, y+radius))
player[2] = Rectangle(Point(x-60-radius,y-radius), Point(x-60+radius, y+radius))
# make poison
poison = {}
def main():
global timer, scoreUI, score, bonus, playerLength, poisonLength, x, y, points, cherryPoints, randomX, randomY, cherryRandomX, cherryRandomY, poisonRandomX, poisonRandomY, key, countDown, k, game
while(game==True):
# score update
scoreUI.undraw()
scoreUI = Text(Point(320,435),score)
scoreUI.setTextColor("white")
scoreUI.setSize(10)
scoreUI.draw(win)
# generating new body blocks
if len(player) < playerLength:
i+=1
player[i] = player[i-1].clone()
# body following player
player[0].undraw()
for i in range(1,len(player)):
player[len(player)-i].undraw()
player[len(player)-i] = player[len(player)-i-1].clone()
player[len(player)-i].draw(win)
# update player's head coordinate
player[0] = Rectangle(Point(x-radius,y-radius), Point(x+radius,y+radius))
player[0].setFill("green")
player[0].setWidth(2)
player[0].draw(win)
# player movement
if keyboard.is_pressed("Up") and key != "Down":
key = "Up"
elif keyboard.is_pressed("Left") and key != "Right":
key = "Left"
elif keyboard.is_pressed("Down") and key != "Up":
key = "Down"
elif keyboard.is_pressed("Right") and key != "Left":
key = "Right"
if key == "Up":
y -= length
elif key == "Left":
x -= length
elif key == "Down":
y += length
elif key == "Right":
x += length
# point
if points == False: # generates new point when eaten
point = Rectangle(Point(randomX-pointRadius,randomY-pointRadius),Point(randomX+pointRadius,randomY+pointRadius))
point.setFill("white")
point.setWidth(2)
point.draw(win)
points = True
if player[0].getCenter().getX() == point.getCenter().getX() and player[0].getCenter().getY() == point.getCenter().getY(): # when player eats the point
point.undraw()
playerLength += 1
poisonLength += 1
score += 200+bonus
randomX = random.choice(coordX)
randomY = random.choice(coordY)
for i in range(len(player)):
if (point.getCenter().getX() == player[i].getCenter().getX() and point.getCenter().getY() == player[i].getCenter().getY()) or (cherryPoints == True and cherryPoint.getCenter().getX() == point.getCenter().getX() and cherryPoint.getCenter().getY() == point.getCenter().getY()): # regenerate x and y coordinate if they share the same coordinate as player and cherry
randomX = random.choice(coordX)
randomY = random.choice(coordY)
for i in range(len(poison)): # regenerate x and y coordinate if point shares the same coordinate to other array of poisons
if point.getCenter().getX() == poison[i].getCenter().getX() and point.getCenter().getY() == poison[i].getCenter().getY():
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
points = False
# cherry
if countDown == 150:
countDown = 0
if cherryPoints == False: # generates new cherry from countdown
cherryPoint = Rectangle(Point(cherryRandomX-pointRadius,cherryRandomY-pointRadius),Point(cherryRandomX+pointRadius,cherryRandomY+pointRadius))
cherryPoint.setFill(color_rgb(213,0,50))
cherryPoint.setWidth(2)
cherryPoint.draw(win)
cherryPoints = True
if cherryPoints == True:
for i in range(2, 6): # cherry blinks between countdown 40 to 100
if countDown == 20*i:
cherryPoint.undraw()
elif countDown == 10+(20*i):
cherryPoint.draw(win)
if countDown >= 100: # when countdown becomes 100, remove cherry and reset count down
cherryPoints = False
countDown = 0
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
if cherryPoints==True and player[0].getCenter().getX() == cherryPoint.getCenter().getX() and player[0].getCenter().getY() == cherryPoint.getCenter().getY(): # when player eats the cherry
cherryPoint.undraw()
score += 500
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
for i in range(len(player)):
if (cherryPoint.getCenter().getX() == player[i].getCenter().getX() and cherryPoint.getCenter().getY() == player[i].getCenter().getY()) or (cherryPoint.getCenter().getX() == point.getCenter().getX() and cherryPoint.getCenter().getY() == point.getCenter().getY()): # regenerate x and y coordinate if they share the same coordinate as player and point
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
for i in range(len(poison)): # regenerate x and y coordinate if cherry shares the same coordinate to other array of poisons
if cherryPoint.getCenter().getX() == poison[i].getCenter().getX() and cherryPoint.getCenter().getY() == poison[i].getCenter().getY():
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
cherryPoints = False
# poison
if poisonLength % 5 == 0: # generates a poison block each time the player size reaches the multiple of 5
poison[k] = Rectangle(Point(poisonRandomX-pointRadius,poisonRandomY-pointRadius),Point(poisonRandomX+pointRadius,poisonRandomY+pointRadius))
poison[k].setFill("green")
poison[k].setWidth(2)
poison[k].draw(win)
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
for i in range(len(player)):
if (poison[k].getCenter().getX() == player[i].getCenter().getX() and poison[k].getCenter().getY() == player[i].getCenter().getY()) or (poison[k].getCenter().getX() == point.getCenter().getX() and poison[k].getCenter().getY() == point.getCenter().getY()) or (cherryPoints==True and poison[k].getCenter().getX() == cherryPoint.getCenter().getX() and poison[k].getCenter().getY() == cherryPoint.getCenter().getY()): # regenerate x and y coordinate if they share the same coordinate as player and point and cherry
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
for i in range(len(poison)):
if poison[k].getCenter().getX() == poison[i].getCenter().getX() and poison[k].getCenter().getY() == poison[i].getCenter().getY(): # regenerate x and y coordinate if new poison shares the same coordinate to other array of poisons
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
bonus+=50
k+=1
poisonLength+=1
# game over requirements
for i in range(len(poison)): # if player touches poison
if player[0].getCenter().getX() == poison[i].getCenter().getX() and player[0].getCenter().getY() == poison[i].getCenter().getY():
game = False
for i in range(2, len(player)): # if player touches its own body or reach out of window
if (player[0].getCenter().getX() == player[i].getCenter().getX() and player[0].getCenter().getY() == player[i].getCenter().getY()) or x < 0 or x > width or y < 0 or y > gridHeight:
game = False
# FPS
update(10)
countDown += 1
# GAME OVER
gameOver = Text(Point(width/2,200), "GAME OVER")
gameOver.setTextColor("red")
gameOver.setSize(30)
gameOver.draw(win)
update()
time.sleep(2)
win.close()
main()
Ideally the result should replace each code in the while loop with individual classes outside of the function to reduce the amount of lines in the main() function and make the script easier to read.
Classes are essentially just bundles of code that contain various attributes and methods.
A Snake class might have a list of coordinates for each section of the body (the first is the head).
class Snake:
def __init__(self, x, y):
self.positions = [(x, y)]
def get_head(self):
return self.positions[0]
def move_forward(self):
self.positions.pop()
self.positions.insert(0, self.get_head()[1] + 1)
def move_backward(self):
self.positions.pop()
self.positions.insert(0, self.get_head()[1] - 1)
...
And so on. Classes, at this level, let you think of objects as concrete entities, distinct from each other but easily manipulated.
I'm trying to figure out why the while loop in one of my functions is still running even after the points in my graphics are equal, which is when I set it to stop. Is there anything I'm doing wrong? I've tried to switch other things around to get it to work but no luck.
It's for a game--when the character reaches the endbox the loop needs to break, but it isn't doing that after I explicitly coded it to. It's in the second function I have:
from graphics import *
def field():
#creating the window
win = GraphWin('The Field',400,400)
win.setBackground('white')
#drawing the grid
boxlist = []
for i in range(0,400,40):
for j in range(0,400,40):
box = Rectangle(Point(i,j),Point(i+40,j+40))
box.setOutline('light gray')
box.draw(win)
boxlist.append(box)
#creating other boxes
startbox = Rectangle(Point(0,0),Point(40,40))
startbox.setFill('lime')
startbox.setOutline('light gray')
startbox.draw(win)
endbox = Rectangle(Point(360,360),Point(400,400))
endbox.setFill('red')
endbox.setOutline('light gray')
endbox.draw(win)
boxlist.append(startbox)
boxlist.append(endbox)
#creating Pete
pete = Rectangle(Point(2,2),Point(38,38))
pete.setFill('gold')
pete.draw(win)
return win,boxlist,pete
def move(win2,boxlist,pete,endbox):
peteloc = pete.getCenter()
#creating loop to move pete
while peteloc != endbox.getCenter():
click = win2.getMouse()
x = click.getX()
y = click.getY()
peteloc = pete.getCenter()
petex = peteloc.getX()
petey = peteloc.getY()
#moving pete
if x>=petex+20 and y<=petey+20 and y>=petey-20:
pete.move(40,0)
elif x<=petex-20 and y<=petey+20 and y>=petey-20:
pete.move(-40,0)
elif y>=petey+20 and x<=petex+20 and x>=petex-20:
pete.move(0,40)
elif y<=petey-20 and x<=petex+20 and x>=petex-20:
pete.move(0,-40)
peteloc = pete.getCenter()
# The main function
def main():
win2,boxlist,pete = field()
endbox = boxlist[len(boxlist)-1]
move(win2,boxlist,pete,endbox)
main()
I think maybe it is caused by precision of float. I guess pete.getCenter() and endbox.getCenter() are something like [float, float], you should avoid using != between float, such as 1.0000001 is not equal to 1.
So even if the character reaches the endbox, the position will still get a little float bias.
So you can change a != b to abs(a - b) > acceptable_error when the error is acceptable. Sample code is like:
# while peteloc != endbox.getCenter():
while abs(peteloc.getX() - endbox.getCenter().getX()) > 0.01 and abs(peteloc.getY() - endbox.getCenter().getY()) > 0.01:
Hope that will help you.
Zelle graphics Point objects don't appear to ever compare as equal:
>>> from graphics import *
>>> a = Point(100, 100)
>>> b = Point(100, 100)
>>> a == b
False
>>>
We have to extract coordinates and do our own comparison. Although #recnac provides a workable solution (+1), I'm going to suggest a more general one. We'll create a distance() method that's valid for any object that inherits from _BBox, which includes Rectangle, Oval, Circle and Line:
def distance(bbox1, bbox2):
c1 = bbox1.getCenter()
c2 = bbox2.getCenter()
return ((c2.getX() - c1.getX()) ** 2 + (c2.getY() - c1.getY()) ** 2) ** 0.5
We can now measure the distance between objects, horizontally, vertically and diagonally. Since your boxes are moving twenty pixels at a time, we can assume that if they are withing 1 pixel of each other, they are in the same location. Your code rewritten to use the distance() method and other tweaks:
from graphics import *
def field(win):
# drawing the grid
boxlist = []
for i in range(0, 400, 40):
for j in range(0, 400, 40):
box = Rectangle(Point(i, j), Point(i + 40, j + 40))
box.setOutline('light gray')
box.draw(win)
boxlist.append(box)
# creating other boxes
startbox = Rectangle(Point(0, 0), Point(40, 40))
startbox.setFill('lime')
startbox.setOutline('light gray')
startbox.draw(win)
boxlist.append(startbox)
endbox = Rectangle(Point(360, 360), Point(400, 400))
endbox.setFill('red')
endbox.setOutline('light gray')
endbox.draw(win)
boxlist.append(endbox)
# creating Pete
pete = Rectangle(Point(2, 2), Point(38, 38))
pete.setFill('gold')
pete.draw(win)
return boxlist, pete
def distance(bbox1, bbox2):
c1 = bbox1.getCenter()
c2 = bbox2.getCenter()
return ((c2.getX() - c1.getX()) ** 2 + (c2.getY() - c1.getY()) ** 2) ** 0.5
def move(win, pete, endbox):
# creating loop to move pete
while distance(pete, endbox) > 1:
click = win.getMouse()
x, y = click.getX(), click.getY()
peteloc = pete.getCenter()
petex, petey = peteloc.getX(), peteloc.getY()
# moving pete
if x >= petex + 20 and petey - 20 <= y <= petey + 20:
pete.move(40, 0)
elif x <= petex - 20 and petey - 20 <= y <= petey + 20:
pete.move(-40, 0)
elif y >= petey + 20 and petex - 20 <= x <= petex + 20:
pete.move(0, 40)
elif y <= petey - 20 and petex - 20 <= x <= petex + 20:
pete.move(0, -40)
# The main function
def main():
# creating the window
win = GraphWin('The Field', 400, 400)
win.setBackground('white')
boxlist, pete = field(win)
endbox = boxlist[-1]
move(win, pete, endbox)
main()
I have a simple block of code that works perfectly on Windows 7 machines and Ubuntu machines, but when I try to run it on 8.1/10 it freezes. I'm not sure why. I've tried 3.0/3.6/2.7 interpreters on variations of the code but it still freezes. Does anyone have a solution? The offending code is the if/else-statement at the bottom.
from graphics import *
def main():
lowx = -10.0
highx = +10.0
lowy = -10.0
highy = +10.0
incx = 0.1
points = []
x = lowx
while x <= highx:
# y = EvaluatePostfix(postfix, x)
if x > 0:
y = x * x
else:
y = x * x * x
points.append((x, y))
x += incx
# Graph
win = GraphWin("My Graphing Calculator", 700, 700)
win.setCoords(lowx, lowy, highx, highy)
for i in range(len(points) - 1):
p1 = Point(points[i][0], points[i][1])
p2 = Point(points[i + 1][0], points[i + 1][1])
line = Line(p1, p2)
line.draw(win)
while (True):
user = input("type your answer")
if user == "hello":
print("there")
else:
print("bad")
win.getMouse() # Pause to view result
win.close() # Close window when done
main()
I am trying to make a program:
simulates a random walk
animates the walk using cs1graphics
starts on center block which is black
takes random steps, never been stepped on turns red, repeat step turns blue.
import random
from cs1graphics import *
from time import sleep
def animationWalk(walk):
print("Animation of Random Walk: ", end = "\n")
window = Canvas(250, 250)
window.setTitle('Random Walk in Manhattan')
for y in range(10) :
for x in range(10) :
cue = Square()
cue.setSize(50)
cue.moveTo(x*25, y*25)
window.add(cue)
(x,y)= (6,6)
squares = Square()
squares.setSize(25)
squares.moveTo((x*25)-14, (y*25)-13)
squares.setFillColor('black')
window.add(squares)
been = Square()
been.setSize(25)
been.moveTo((x*25)-14, (y*25)-13)
window.add(been)
for direction in range (len(walk)):
if walk[direction] == 'N':
#y -= 1
(x,y)=(x,y-1)
elif walk[direction] == 'E':
#x += 1
(x,y)=(x+1,y)
elif walk[direction] == 'S':
#y += 1
(x,y) =(x,y+1)
elif walk[direction] == 'W':
#x -= 1
(x,y) = (x-1,y)
been.setSize(25)
been.moveTo((x*25)-14, (y*25)-13)
been.setFillColor('red')
cue.setSize(25)
sleep(0.25)
cue.moveTo((x*25)-14, (y*25)-13)
cue.setFillColor('blue')
def randomWalk(x,y):
block = []
for i in range (x):
block.append([])
for i in block:
for j in range(y):
i.append(0)
position = (x//2, y//2)
h = position[0]
v = position[1]
walk = ''
block[h][v] += 1
while (h != -1) and (h != (x-1)) and (v != -1) and (v != (y-1)):
directions = random.randrange(1,5)
if directions == 1:
v += 1
walk = walk + 'E'
elif directions == 2:
h += 1
walk = walk + 'S'
elif directions == 3:
v -= 1
walk = walk + 'W'
elif directions == 4:
h -= 1
walk = walk + 'N'
block[h][v] += 1
print("Starting at Center (", x//2, ",", y//2, ")")
print("Walking Directions: ", walk)
print("Track of Random Walk:", end = "\n")
for entry in block:
print(entry)
animationWalk(walk)
def main(): ## define main program
x = 10
y = 10
randomWalk(x,y)
main()
The color of a square is supposed to change to red when it is visited, blue when it is revisited and is changed back to red when it is passed. I cant get the blocks to maintain the color after it has been stepped off of.
I am using curses in python, and I am trying to create a game where you print out characters in the terminal window. the field is then supposed to be saved in a text file if you press 's' and if you press 'o' the saved playing field is supposed to be uploaded. I manage to store all characters in an array, but i don't know how to upload the file back/print it on the terminal window.
So the problem is that i don't know how to 'reload' the characters i have stored.
The saved txt.file looks like this:
[' ', ' ', 'f', 'i', ' '....]
[' ', 'f', ' ', ' ', ' '....]
[...
[...
etc
My program.....
import curses
def main(scr):
"""
Draw a border around the screen, move around using the cursor and leave a mark
of the latest pressed character on the keyboard.
Quit using 'q'.
"""
# Clear the screen of any output
scr.clear()
# Get screen dimensions
y1, x1 = scr.getmaxyx()
y1 -= 1
x1 -= 1
y0, x0 = 0, 0 #min
# Get center position
yc, xc = (y1-y0)//2, (x1-x0)//2
# Draw a border
scr.border()
# Move cursor to center
scr.move(yc, xc)
# Refresh to draw out
scr.refresh()
#Make a copy of the playing field
array = [[' ' for _ in range(x1-1)] for _ in range(y1-1)]
# Main loop
x = xc
y = yc
ch = 'j'
while True:
key = scr.getkey()
if key == 'q':
break
elif key == 'KEY_UP' and (y-1) > y0:
y -= 1
elif key == 'KEY_DOWN' and (y+1) < y1:
y += 1
elif key == 'KEY_LEFT' and (x-1) > x0:
x -= 1
elif key == 'KEY_RIGHT' and (x+1) < x1:
x += 1
elif key == 's':
text_file = open("border.txt", "w")
for char in array:
text_file.write("%s\n" % char)
text_file.close()
elif key == 'o':
scr.clear()
saved_file = open("border.txt", "r")
scr.addstr... # this is the part that don't work.
scr.refresh()
else:
if key != 'KEY_UP' and key != 'KEY_DOWN' and key != 'KEY_LEFT' and key != 'KEY_RIGHT':
ch = key
#place the key in the array
posY = y
posX = x
if y >= y0 and x >= x0 and y <= (y1) and x <= (x1):
array[int(posY-1)][int(posX-1)] = ch
# Draw out the char at cursor positino
scr.addstr(ch)
# Move cursor to new position
if y < y1 and y > y0 and x > x0 and x < x1:
scr.move(y, x)
# Redraw all items on the screen
scr.refresh()
You can try to store your data with the python pickle module. It is intended for serialization of data structures like this. Later on you can reload your structure with pickle again