I would like to see on screen a sign, e.x might be (hash) '#'. Sign will have some starting position, let's say (0, 0). I would like to see sign moving right if I press right arrow, left if I press left arrow, etc.
So far my code looks like this, and it works for reading pos, but I want to add some kind of "animation" so I can see sign is moving on the screen:
!Update: Just to give u a clue, I created "icon" and now when u press right or left, icon moves in desired direction.
from msvcrt import getch
icon = chr(254)
pos = [0, 0]
t = []
def fright():
global pos
pos[0] += 1
print ' ' * pos[0],
print(icon)
def fleft():
global pos
pos[0] -= 1
print ' ' * pos[0],
print(icon)
def fup():
global pos
pos[1] += 1
def fdown():
global pos
pos[1] -= 1
def appendTab():
global pos, t
t.append(pos)
while True:
print'Distance from zero: ', pos
key = ord(getch())
if key == 27: #ESC
break
elif key == 13: #Enter
print('selected')
appendTab()
elif key == 32: #Space, just a small test - skip this line
print('jump')
print(t)
elif key == 224: #Special keys (arrows, f keys, ins, del, etc.)
key = ord(getch())
if key == 80: #Down arrow
print('down')
fdown()
elif key == 72: #Up arrow
print('up')
fup()
elif key == 75: #Left arrow
print('left')
fleft()
elif key == 77: #Right arrow
print('right')
fright()
You could create a list of lists that serves as the map and set the cell of the player to '#'. Then just print the map and if the player moves, clear the command-line/terminal with os.system('cls' if os.name == 'nt' else 'clear') and print the updated map.
import os
from msvcrt import getch
pos = [0, 0]
# The map is a 2D list filled with '-'.
gamemap = [['-'] * 5 for _ in range(7)]
# Insert the player.
gamemap[pos[1]][pos[0]] = '#'
while True:
print('Distance from zero: ', pos )
key = ord(getch())
if key == 27: #ESC
break
elif key == 224: #Special keys (arrows, f keys, ins, del, etc.)
key = ord(getch())
if key in (80, 72, 75, 77):
# Clear previous tile if player moves.
gamemap[pos[1]][pos[0]] = '-'
if key == 80: #Down arrow
pos[1] += 1
elif key == 72: #Up arrow
pos[1] -= 1
elif key == 75: #Left arrow
pos[0] -= 1
elif key == 77: #Right arrow
pos[0] += 1
print('clear')
# Clear the command-line/terminal.
os.system('cls' if os.name == 'nt' else 'clear')
# Set the player to the new pos.
gamemap[pos[1]][pos[0]] = '#'
# Print the map.
for row in gamemap:
for tile in row:
print(tile, end='')
print()
Related
I'm trying to build a Snake game using python, but I'm struggling with the input system. In the snake game, the snake walks through the same direction until someone change his direction.
The way I did was stopping the snake from moving while waits for the next key, but that's not what I want. The snake must walk to the same direction until receive an input to change direction.
How to do the get the key so the snake changes his direction while moving it through the screen and colliding with objects?
import os
from msvcrt import getch
class SnakeGame(object):
screen = None
def __init__(self, rows_count, column_count):
self.screen = self.initialize_screen(rows_count, column_count)
self.collided = False
def initialize_screen(self, rows_count, column_count):
#creates the 2D list with 0 in all values
screen = [[0 for x in range(column_count)] for y in range(rows_count)]
#get the rows
for row in range(len(screen)):
if row == 0 or row == len(screen) - 1:
screen[row] = self.add_same_value_entire_list(screen[row], 1)
else:
for column in range(len(screen[row])):
if column == 0 or column == len(screen[row]) - 1:
screen[row][column] = 1
return screen
def add_same_value_entire_list(self, list, value):
populatedList = [value for i in range(len(list))]
return populatedList
def print_screen(self):
screen_text = ''
for row in self.screen:
for column in row:
screen_text = screen_text + self.translated_value(column)
screen_text = screen_text + '\n'
return screen_text
def translated_value(self, value):
if value == 1:
return '#'
elif value == 2:
return '*'
elif value == -1: #snake body
return 'O'
elif value == -2: #moving left snake head left <----
return '<'
elif value == -3: #moving right snake head right ---->
return '>'
elif value == -4: #moving down
return 'V'
elif value == -5: #moving up
return '^'
else:
return ' '
def play(self):
player = Player()
key_pressed = 9999
self.add_player_to_screen(player)
while(self.defeated() is not True and key_pressed != 27):
self.clear()
print(self.print_screen())
key_pressed = self.read_key()
player.move(self.translate_key(key_pressed))
self.add_player_to_screen(player)
def read_key(self):
return ord(getch())
def add_player_to_screen(self, player):
print(player.location_x)
print(player.location_y)
if(player.position_cordination == 'E'):
self.screen[player.location_x][player.location_y - 1] = 0
elif (player.position_cordination == 'W'):
self.screen[player.location_x][player.location_y + 1] = 0
elif (player.position_cordination == 'N'):
self.screen[player.location_x + 1][player.location_y] = 0
elif (player.position_cordination == 'S'):
self.screen[player.location_x - 1][player.location_y] = 0
if(self.screen[player.location_x][player.location_y] == 0):
self.screen[player.location_x][player.location_y] = player.body
elif(self.screen[player.location_x][player.location_y] < 0):
self.collided = True
def translate_key(self, key):
print (key)
if (key == 224):
key = ord(getch())
print(key)
if (key == 72):
return 'N'
elif (key == 80):
return 'S'
elif (key == 75):
return 'W'
elif (key == 77):
return 'E'
else:
pass
def defeated(self):
return self.collided
def clear(self):
os.system('cls' if os.name=='nt' else 'clear')
class Player(object):
def __init__(self):
self.nodes_size = 1
self.position_cordination = 'E'
self.last_cordination = 'E'
self.location_x = 4
self.location_y = 4
self.body = -3
def draw(self):
body = ''
for index in range(self.nodes_size):
if(index == 0 and self.position_cordination == 'E'):
body = '>'
elif(index == 0 and self.position_cordination == 'W'):
body = '<'
elif(index == 0 and self.position_cordination == 'N'):
body = '^'
elif(index == 0 and self.position_cordination == 'S'):
body = 'V'
else:
body += '-'
return body
def move(self, cordination):
print("Cordinations x = " + str(self.location_x) + " y = " + str(self.location_y))
if (self.position_cordination != 'S' and cordination == 'N'):
self.location_x -= 1
self.body = -5
elif (self.position_cordination != 'N' and cordination == 'S'):
self.location_x +=1
self.body = -4
elif (self.position_cordination != 'W' and cordination == 'E'):
self.location_y += 1
self.body = -3
elif (self.position_cordination != 'E' and cordination == 'W'):
self.location_y -= 1
self.body = -2
else:
pass
self.position_cordination = cordination
print("Cordinations x = " + str(self.location_x) + " y = " + str(self.location_y))
snake = SnakeGame(32, 32)
snake.play()
I am coding a simple maze game. I've created a Player class with a move method -- but whenever I want to check if the move is in the available paths list, it does run the move method and changes my character position.
class Player :
def __init__ (self, position):
self.position = position
def move (self, direction):
if direction == "right": self.position[0] += 1
elif direction == "left": self.position[0] -= 1
elif direction == "up": self.position[1] -= 1
elif direction == "down": self.position[1] += 1
return self.position
maze_paths = [[0,0], [1,0]]
mac = Player([0,0])
direction = 'left'
if mac.move(direction) in maze_paths:
print('ok')
else:
print('No way!')
print('Final position is: %r' % (mac.position))
The output I expect is:
No way!
Final position is: [0, 0]
...because the move left shouldn't be allowed with the maze as it's defined. However, what we have instead is:
No way!
Final position is: [-1, 0]
...with the move happening even though it shouldn't be allowed.
As #TimRichardson suggested in the comments, the act of calculating state should be split out from the act of changing state. Functional programming languages are built to make this easy, but Python isn't one -- so you need to jump through some hoops.
Consider splitting move into two methods, like the calculate_move and do_move shown below:
class Player:
def calculate_move(self, direction):
"""Calculate where we would be if we moved in a direction"""
emulated_position = self.position[:] # make a copy
if direction == "right": emulated_position[0] += 1
elif direction == "left": emulated_position[0] -= 1
elif direction == "up": emulated_position[1] -= 1
elif direction == "down": emulated_position[1] += 1
return emulated_position
def do_move(self, direction):
"""Actually move in the given direction"""
self.position = self.calculate_move(direction)
maze_paths = [[0,0], [1,0]]
mac = Player([0,0])
direction = 'left'
if mac.calculate_move(direction) in maze_paths:
mac.do_move(direction)
print('ok')
else:
print('No way!')
print('Final position is: %r' % mac.position)
...which properly emits as output:
No way!
Final position is: [0, 0]
Create a meningful separate validate function like. Did this on my phone.
def validateMove(direction):
if direction == "right":
return self.position[0] + 1 in self.maze_paths
if direction == "down":
return self.position[1] + 1 in self.maze_paths
if direction == "left":
return self.position[0] - 1 in self.maze_paths
if direction =="up":
return self.position[1] - 1 in self.maze_paths
return false
Hi I am trying to get the following github repo : https://github.com/lukekulik/solar-system
to work on my laptop and have installed all the modules required but for some reason when i try and run i get error cannot import module vis in from vis import ....
It is in every file and i a using python 3.6.
The code for one file is below:
from vis import scene, label, vector, norm, cross
Error is here when trying to import vis and below when trying to import wx
#from pygame.mixer import music
from parameters import planets, n, am
from wx import Exit
lbl = label(text=" Simulation is paused. \n Press any key to continue.",
visible=False, box=False)
# key_check function translates user keyboard into commands for the program:
def key_check(ship_mode, s, v, a, dt, sw_lbl, lbl_off, predraw, earthpos, t,
ship):
if scene.kb.keys: # check if there are any keys pressed in the queue
key = scene.kb.getkey() # retrieve the pressed key
# change simulation speed: (steps are small on purpose; user has to
press and hold for smooth transition)
if key == 'q' and 1 <= dt < 125:
dt += 2
elif key == 'q' and dt <= 0.95:
dt += 0.05
elif key == 'a' and dt > 1:
dt -= 2
elif key == 'a' and 0.2 < dt <= 1:
dt -= 0.05
elif key == 'esc':
Exit() # exit the program
elif key == 'p':
lbl.visible = True # show pause label
lbl.pos = scene.center # center the label on the screen
scene.kb.getkey() # wait for key input
lbl.visible = False # hide pause label
elif key == 'x':
if scene.stereo == 'nostereo':
scene.stereo = 'redcyan' # turn on 3D rendering mode (red-cyan)
elif scene.stereo == 'redcyan':
scene.stereo = 'crosseyed' # turn on 3D rendering mode (cross-eyed)
else:
scene.stereo = 'nostereo' # turn off 3D rendering mode
elif key == 'l':
sw_lbl = not sw_lbl # planet/spaceship label switch
lbl_off = not lbl_off
elif key == 's':
#if ship_mode:
# music.fadeout(2500) # fade out music when quitting spaceship mode
# else:
# music.play(-1) # turn on music when entering spaceship mode
ship_mode = not ship_mode # spaceship mode switch
a = vector(0, 0, 0) # reset acceleration
sw_lbl = True # turn on spaceship label
# spaceship thrusters control:
elif key == 'up':
#a += vector(0, 0, am) # old cartesian steering
a += am*norm(v) # accelerate into the direction of motion
elif key == 'down':
a -= am*norm(v) # accelerate against the direction of motion
elif key == 'left':
a -= am*cross(norm(v),cross(norm(v),norm(s))) # accelerate to the left of the velocity
elif key == 'right':
a += am*cross(norm(v),cross(norm(v),norm(s))) # accelerate to the right of the velocity
elif key == 'd':
a += am*cross(norm(v),norm(s)) # accelerate to the 'top' of the velocity
elif key == 'c':
a -= am*cross(norm(v),norm(s)) # accelerate to the 'bottom' of the velocity
elif key == '0':
a = vector(0, 0, 0) # reset acceleration
# pre-programmed spaceship positions/scenarios:
elif key == '1': # Earth-Sun Lagrange point 3 (L3 - 'counter-Earth')
s = -earthpos
v0 = (planets[2][1][:, (int(-t + 1)) % n] - planets[2][1][:, (int(-t)) % n]) / (365.25 * 86400 / n)
v = vector(v0[0], v0[1], v0[2])
a = vector(0, 0, 0)
predraw = False
ship.trail.append(pos=s, retain=1)
elif key == '2': # polar orbit around the Sun
s = vector(3e+07, -2e+06, 2e+08)
v = vector(0, 24, 0)
a = vector(0, 0, 0)
predraw = False
ship.trail.append(pos=s, retain=1)
elif key == '3': # orbit of the probe Helios 2 (fastest man-made object to date - 0.02% speed of light)
s = vector(43e6, 0, 0) # perihelion
v = vector(0, 0, 70.22)
a = vector(0, 0, 0)
predraw = False
ship.trail.append(pos=s, retain=1)
elif key == '4': # Halley's comet (derived using specific orbital energy, 162.3 deg inclination)
s = vector(87813952, 0, 0) # perihelion
v = vector(0, 16.7, 52)
a = vector(0, 0, 0)
predraw = False
ship.trail.append(pos=s, retain=1)
return ship_mode, s, v, a, dt, sw_lbl, lbl_off, predraw, ship
def mouse_check(obj, sw_lbl, lbl_off, ship_mode):
if scene.mouse.clicked and not ship_mode: # check if there are any
clicks
in the queue
scene.mouse.getclick() # retrieve the click
obj_old = obj
obj = scene.mouse.pick # clicked object becomes main object
try:
r = obj.radius
except AttributeError:
obj = obj_old # if the clicked object is not a sphere (e.g. Saturn's rings), go back to old_obj
else:
if r > 30000000000: # if the clicked object is a very large sphere (celestial), go back to old_obj
obj = obj_old
if obj != obj_old and not lbl_off: # if different planet was clicked, switch planet label ON
sw_lbl = True
scene.center = obj.pos # center scene on the main object
return obj, sw_lbl`
Thanks in advance.
I'm currently making a snake game in python (IDLE 3.6.0) and it keeps coming up with an error called 'break' outside loop. What does that mean? What am I doing wrong. This is the first time I've ever come accross this error.
Here's my code:
# SNAKES GAME
# Use ARROW KEYS to play, SPACE BAR for pausing/resuming and Esc Key for exiting
import curses
from curses import KEY_RIGHT, KEY_LEFT, KEY_UP, KEY_DOWN
from random import randint
curses.initscr()
win = curses.newwin(20, 60, 0, 0)
win.keypad(1)
curses.noecho()
curses.cur_set(0)
win.border(0)
win.nodelay(1)
key = KEY_RIGHT # Initalizing Values
score = 0
snake = [[4,10], [4,9], [4,8]] # Initial snake co-ordinates
food = [10,20] # First food co-ordinates
win.addc(food[0], food[1], '*') # Prints the food
while key != 27:
win.border(0)
win.addstr(0, 2, 'Score :' + str(score) + ' ') # Printing 'Score' and
win.addstr(0, 27, ' SNAKE ') # 'SNAKE' strings
win.timeout(150 - (len(snake)/5 + len(snake)/10)%120)
prevKey = key # Previous key pressed
event = win.getch
key = key if event == -1 else event
if key == ord(' '): # If SPACE BAR is pressed, wait for another
key = -1 # one (Pause/Resume)
while key != ord(' '):
key = win.getch()
key = prevKey
continue
if key not in [KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, 27]: # If an invalid key is pressed
key = prevKey
# Calculates the new coordinates of the head of the snake. NOTE: len(snake) increases.
# This is taken care of later at [1].
snake.insert(0, [snake[0][0] + (key == KEY_DOWN and 1) + (key == KEY_UP and -1), snake[0][1] + (key == KEY_LEFT and -1) + (key == KEY_RIGHT and 1)])
# If snake crosses the boundaries, make it enter from the other side
if snake[0][0] == 0: snake[0][0] = 18
if snake[0][1] == 0: snake[0][1] = 58
if snake[0][0] == 19: snake[0][0] = 1
if snake[0][1] == 59: snake[0][1] = 1
# Exit if snake crosses the boundaries (Uncomment to enable)
# if snake[0][0] == 0 or snake[0][0] == 19 or snake[0][1] == 0 or snake[0][1] == 59: break
# If snake runs over itself
if snake[0]in snake[1:]: break
if snake[0] == food:
food = []
score += 1
while food == []:
food = [randint(1, 18), randint(1, 58)]
if food in snake: food = []
win.addch(food[0], food[1], '*')
else:
last = snake.pop()
win.addch(last[0], last[1], ' ')
win.addch(snake[0][0], snake[0][1], '#')
curses.erdwin()
print("\nScore - " + str(score))
print("http://bitemelater.in\n")
I'd be glad if you could help! Thanks!
The line that says if snake[0]in snake[1:]: break is where your error is stemming from. You probably want to use some kind of game ending function to display points and high scores and such:
def end_game():
#do your game ending things here
Then you would call that function here:
if snake[0]in snake[1:]: end_game()
EDIT:
I found this in relation to your curses error: Error no module named curses. It seems as if curses doesn't support Windows machines. Try installing UniCurses or this binary.
def menurender():
global pos
global menulist
line1=menulist[pos]
if pos == len(menulist):
line2="back"
else:
line2=menulist[pos+1]
lcd.clear()
lcd.message(str(pos)+' ' +line1+ "\n"+str(pos+1)+' '+ line2)
In my block of code, I have a conditional in the menurender() function that checks to make sure that the list menulist has a valid index before referencing it, but i receive IndexError: list index out of range. I understand that the else statement is causing it, but I am confused because python shouldn't be executing it.
Full code
#!/usr/bin/python
#################################################
#IMPORTS#########################################
#################################################
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
from Adafruit_I2C import Adafruit_I2C
#################################################
#OBJECTS#########################################
#################################################
lcd = Adafruit_CharLCDPlate()
#################################################
#VARIABLES#######################################
#################################################
#current button value
prevbutton = "NULL"
#for SELECT key and determining clicks
action = False
#variable for menu position
pos = 0
#on screen cursor 0 for top line, 1 for bottom line
cursor = 0
#Handles list structure and action when clicked
menulist= []
menulist.append("CPU")
menulist.append("RAM")
menulist.append("STORAGE")
menulist.append("NETWORK")
#get input from keys and return the currently pressed key
def buttonstatus():
bstatus = "Null"
if lcd.buttonPressed(lcd.SELECT) == True:
bstatus="SELECT"
elif lcd.buttonPressed(lcd.UP) == True:
bstatus="UP"
elif lcd.buttonPressed(lcd.DOWN) == True:
bstatus="DOWN"
elif lcd.buttonPressed(lcd.LEFT) == True:
bstatus="LEFT"
elif lcd.buttonPressed(lcd.RIGHT) == True:
bstatus="RIGHT"
return bstatus
#checks buttons pressed and converts that into action for top menu
def getinput():
global prevbutton
global pos
if buttonstatus() != prevbutton:
prevbutton = buttonstatus()
if buttonstatus() == "SELECT":
print "select"
elif buttonstatus() == "DOWN":
pos = pos + 1
elif buttonstatus() == "UP":
pos = pos -1
#elif buttonstatus() == "LEFT":
#print "left"
#elif buttonstatus() == "RIGHT":
#print "right"
#defines bounds for the position of the cursor
def posbounds():
global pos
global menulist
if pos < 0:
pos = 0
if pos == len(menulist):
pos = len(menulist)
#code renders the menu on the LCD
def menurender():
global pos
global menulist
line1=menulist[pos]
if pos == len(menulist):
line2="back"
else:
line2=menulist[pos+1]
lcd.clear()
lcd.message(str(pos)+' ' +line1+ "\n"+str(pos+1)+' '+ line2)
while True:
getinput()
posbounds()
menurender()
There are lots if values for pos != len(menulist) for which menulist[pos+1] gives an IndexError (including pos == len(menulist) - 1). You should check
if pos > (len(menulist) - 2):
You should probably change if pos == len(menulist): to if pos == len(menulist) - 1: if you want to check if pos is the index of the last element, or to if pos == len(menulist) - 2: if you want to check for the second to last element.
A better way of doing this may be by using a try ... except block.
try:
line2 = menulist[pos+1]
except IndexError:
# Out of range -> pos is greater than len(menulist)-1
line2 = 'back'
However - this doesn't seem lika a Pythonic way of doing anything at all in Python. Maybe you could tell us what you are trying to achieve, and someone here may propose a better way of doing it.