'break' outside loop in snake game - python

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.

Related

How do I add my current code fit into a main menu screen with Python Curses?

I'm working on a snake game for a school assignment in Python Curses but the code I have written doesn't have a menu option and I am looking for one that will work for it. I really just need a play button to enter the game and an exit button to quit out of it. I've tried lots of methods but some either don't show up or I can't put the code in the selected button.
I have tried setting them in rows as I have seen two tutorials do. One required me to change my game code with a dif code to work but it didn't make any menu show up. (Code gotten from here https://www.youtube.com/watch?v=RXEOIAxgldw) The other had a simple menu which was very close to working as it did show up but didn't have a tutorial on how to connect it to the snake game as the same user had made a snake game as well. It's the one I had the most luck with but I can't figure out how to set it up so that when I chose "Play" it will play the game and when I chose "Exit" it will clear the game and stop running as when I select Exit the code doesn't stop and it goes back to a broken version of the snake game. (Code gotten from here https://www.youtube.com/watch?v=zwMsmBsC1GM)
Here is what my snake code looks like. All I need is a Play and Exit button and was wanting to know what would be the best way for that to work without altering my snake code too much. I'm a beginner to coding in curses so any help would be much appreciated.
`
import curses
from random import randint
curses.initscr()
win = curses.newwin(20, 60, 0, 0)
win.keypad(1)
curses.noecho()
curses.curs_set(0)
win.border(0)
win.nodelay(1)
snake = [(4, 10), (4, 9), (4, 8)]
food = (10, 20)
score = 0
win.addch(food[0], food[1], '©')
ESC = 27
key = curses.KEY_RIGHT
while key != ESC:
win.addstr(0, 2, 'Score ' + str(score) + ' ')
win.timeout(150 - (len(snake)) // 5 + (len(snake) // 10 % 120))
event = win.getch()
prev_key = key
key = event if event != -1 else prev_key
if key not in [
curses.KEY_LEFT, curses.KEY_RIGHT, curses.KEY_UP, curses.KEY_DOWN,
ESC
]:
key = prev_key
y = snake[0][0]
x = snake[0][1]
if key == curses.KEY_DOWN:
y += 1
if key == curses.KEY_UP:
y -= 1
if key == curses.KEY_LEFT:
x -= 1
if key == curses.KEY_RIGHT:
x += 1
snake.insert(0, (y, x))
if y == 0: break
if y == 19: break
if x == 0: break
if x == 59: break
if snake[0] in snake[1:]: break
if snake[0] == food:
score += 1
food = ()
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.endwin()
print(f"Game over! Final score= {score}")
`

how do i disappear food from inside snake with python?

I want to make the food disappear from the snake when it eats the food but the string stays visible inside snake making the snake look weird with the food in the snake... now what I been trying is this line of code:
Error ( 'tuple' object has no attribute 'replace' )
for food in snake:
food = food.replace(food, ' ')
I just started writting code not too long ago... i only know the basics of python but still confusing and I'm trying to learn as i work in this project to make the game better...
This is the python Script:
import curses
from mimetypes import init
from random import randint
WINDOW_WIDTH = 60
WINDOW_HEIGHT = 20
# Set Up
curses.initscr()
win = curses.newwin(WINDOW_HEIGHT, WINDOW_WIDTH, 0, 0) # y, x
win.keypad(1)
curses.noecho()
curses.curs_set(0)
win.border(0)
win.nodelay(1)
# Snake And Food
snake = [(4, 10), (4, 9), (4, 8)]
food = (10, 10)
win.addch(food[0], food[1], '⊠')
# Game Logic
score = 0
ESC = 27
key = curses.KEY_RIGHT
while key != ESC:
win.addstr(0, 2, 'score ' + str(score) + ' ')
win.timeout(150 - (len(snake)) // 5 + len(snake)//10 % 120)
prev_key = key
event = win.getch()
key = event if event != -1 else prev_key
if key not in [curses.KEY_LEFT, curses.KEY_RIGHT, curses.KEY_UP, curses.KEY_DOWN, ESC]:
prev_key
# Calculating Coordinates
y = snake[0][0]
x = snake[0][1]
if key == curses.KEY_DOWN:
y += 1
if key == curses.KEY_UP:
y -= 1
if key == curses.KEY_LEFT:
x -= 1
if key == curses.KEY_RIGHT:
x += 1
snake.insert(0, (y, x))
# Hit Border Reboot
if y == 0: break
if y == WINDOW_HEIGHT-1: break
if x == 0: break
if x == WINDOW_WIDTH-1: break
# dead.Self Snake
if snake[0] in snake[1:]: break
if snake[0] == food:
# Eat The Food
score += 1
food = ()
while food == ():
food = (randint(1,WINDOW_HEIGHT-2), randint(1,WINDOW_WIDTH-2))
if food in snake:
food = ()
win.addch(food[0], food[1], '⊠')
else:
# Move Snake
last = snake.pop()
win.addch(last[0], last[1], ' ')
win.addch(snake[0][0], snake[0][1], '▇')
# Working in Making the food Disappear inside snake
curses.endwin()
print(f"Final score = {score}")
I'm trying to figure out if it goes at the bottom of the code or somewhere else... I try a few things ex: While, If, and different variables...
P.s. ((I just wrote the code but is not mines I did'nt copy & paste neither...))
Please Help!!....

How do I prevent this Integer expectation error?

I'm making a simple little snake game as coding practice.
While trying to add the tail character to the window, I get this error. I know that I am not giving it integers, but I do not know what to do differently in order to.
Here is the error:
line 56, in <module>
w.addch(tail[0], tail[1], ' ')
TypeError: integer argument expected, got float
Here is the part generating error:
else:
tail = snake.pop()
w.addch(tail[0], tail[1], ' ')
Heres the full code:
import random
import curses
s = curses.initscr()
curses.curs_set(0)
sh, sw = s.getmaxyx()
w = curses.newwin(sh, sw, 0, 0)
w.keypad(1)
w.timeout(100)
snk_x = sw/4
snk_y = sh/2
snake = [
[snk_y, snk_x],
[snk_y, snk_x-1],
[snk_y, snk_x-2]
]
food = [sh/2, sw/2]
w.addch(food[0], food[1], curses.ACS_PI)
key = curses.KEY_RIGHT
while True:
next_key = w.getch()
key = key if next_key == -1 else next_key
if snake[0][0] in [0, sh] or snake[0][1] in [0, sw] or snake[0] in snake[1:]:
curses.endwin()
quit()
new_head = [snake[0][0], snake[0][1]]
if key == curses.KEY_DOWN:
new_head[0] += 1
if key == curses.KEY_UP:
new_head[0] -= 1
if key == curses.KEY_RIGHT:
new_head[1] += 1
if key == curses.KEY_LEFT:
new_head[1] -= 1
snake.insert(0, new_head)
if snake[0] == food:
food = None
while food is None:
nf = [
random.randinit(1, sh-1),
random.randinit(1, sw-1)
]
food = nf if nf not in snake else None
w.addch(food[0], food[1], curses.ACS_PI)
else:
tail = snake.pop()
w.addch(tail[0], tail[1], ' ')
w.addch(snake[0][0], snake[0][1], curses.ACS_CKBOARD)
I cant think of a way to be more direct so this is me filling the text requirements.
reference for code?:
s = screen, snk_x/y = Snake x/y, sw/sh = screen width/height, w = window.
If I can be anymore clear let me know.
addch expects int. But division of integers in python 3 returns float.
You can:
convert the numbers to int w.addch(int(food[0]), int(food[1]), curses.ACS_PI)
or you can use // instead of / to do integer division
You can try just casting the values to integers using int() as follows:
w.addch(int(tail[0]), int(tail[1]), ' ')

python keypress simple game

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()

Curses snake game not removing cells in linux os

It's code from a curses tutorial that I've been using to get a grasp of it but even though I've checked the code multiple times, it's still not removing the old cells. The guy that wrote the code is on a mac and I'm using linux so would that be a problem?
import curses
import time
import random
screen = curses.initscr()
dims = screen.getmaxyx()
def game():
screen.nodelay(1)
head = [1, 1]
body = [head[:]]*5
screen.border()
direction = 0 # 0:right, 1:down, 2:left, 3:up
gameover = False
while not gameover:
deadcell = body[-1][:]
if deadcell not in body:
screen.addch(deadcell[0], deadcell[1], ' ')
screen.addch(head[0], head[1], 'X')
if direction == 0:
head[1] += 1
elif direction == 2:
head[1] -= 1
elif direction == 1:
head[0] += 1
elif direction == 3:
head[0] -= 1
deadcell = body[-1][:]
for z in range(len(body)-1, 0, -1):
body[z] = body[z-1][:]
body[0] = head[:]
if screen.inch(head[0], head[1]) != ord(' '):
gameover = True
screen.move(dims[0]-1, dims[1]-1)
screen.refresh()
time.sleep(0.1)
game()
curses.endwin()
The problem seems to be near the lines:
while not gameover:
deadcell = body[-1][:]
if deadcell not in body:
screen.addch(deadcell[0], deadcell[1], ' ')
deadcell is always going to be in body, so no cells will ever get cleared.
Try this instead:
deadcell = body[-1][:]
while not gameover:
if deadcell not in body:
screen.addch(deadcell[0], deadcell[1], ' ')

Categories

Resources