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!!....
Related
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}")
`
I'm trying to make a simple console tic tac toe in Python.
What I want is to let the player to choose the position is going to do the next play by moving the cursor with arrow keys
By investigating a bit I've already been able to replace actual strings in a board's position with str.format() and changing the string that position has with an array by an user input.
The following code shows how I achived that.
It only replaces the first position as just an example .
from os import system
board = ["a",'b','c','c','d','e','f','g','h']
#Draws the board
def drawboard():
print(" {0[0]} | {0[1]} | {0[2]} ".format(board))
print("___|___|___")
print(" {0[3]} | {0[4]} | {0[5]} ".format(board))
print("___|___|___")
print(" {0[6]} | {0[7]} | {0[8]} ".format(board))
print(" | | ")
drawboard()
userInput = input()
board[0] = userInput
system("cls") #clears the screen
drawboard()
Writing Tic Tac Toe in console can be done using curses. Its API is pretty straight forward for working with display coordinates. This script will work as described by you above, allowing to navigate with the arrow keys and putting on a key stroke the respective X or O signs. I works well in my shell
import curses
CH_P1 = 'X'
CH_P2 = 'O'
X_STEP = 4
Y_STEP = 2
X_OFFSET = 1
Y_OFFSET = 4
def print_board(stdscr):
stdscr.addstr(0, 0, 'Tic Tac Toe')
stdscr.hline(1, 0, '-', 50)
stdscr.addstr(2, 0, 'Use arrows to move, [SPACE] Draw, [Q] Quit')
stdscr.addstr(Y_OFFSET , X_OFFSET, ' │ │ ')
stdscr.addstr(Y_OFFSET + 1, X_OFFSET, '──┼───┼──')
stdscr.addstr(Y_OFFSET + 2, X_OFFSET, ' │ │ ')
stdscr.addstr(Y_OFFSET + 3, X_OFFSET, '──┼───┼──')
stdscr.addstr(Y_OFFSET + 4, X_OFFSET, ' │ │ ')
def print_players(stdscr, player_id):
stdscr.addstr(Y_OFFSET + 6, 0, 'Player {}'.format(CH_P1),
curses.A_BOLD if player_id == 0 else 0)
stdscr.addstr(Y_OFFSET + 7, 0, 'Player {}'.format(CH_P2),
curses.A_BOLD if player_id == 1 else 0)
def draw(y, x, stdscr, player_id):
stdscr.addch(y, x, CH_P2 if player_id else CH_P1)
def check_victory(board, y, x):
#check if previous move caused a win on horizontal line
if board[0][x] == board[1][x] == board [2][x]:
return True
#check if previous move caused a win on vertical line
if board[y][0] == board[y][1] == board [y][2]:
return True
#check if previous move was on the main diagonal and caused a win
if x == y and board[0][0] == board[1][1] == board [2][2]:
return True
#check if previous move was on the secondary diagonal and caused a win
if x + y == 2 and board[0][2] == board[1][1] == board [2][0]:
return True
return False
def main(stdscr):
# Clear screen
# stdscr.clear()
print_board(stdscr)
player_id = 0
print_players(stdscr, player_id=player_id)
x_pos = 1
y_pos = 1
board = [list(' ') for _ in range(3)]
# This raises ZeroDivisionError when i == 10.
while True:
stdscr.move(Y_OFFSET + y_pos * Y_STEP, X_OFFSET + x_pos * X_STEP)
c = stdscr.getch()
if c == curses.KEY_UP:
y_pos = max(0, y_pos - 1)
elif c == curses.KEY_DOWN:
y_pos = min(2, y_pos + 1)
elif c == curses.KEY_LEFT:
x_pos = max(0, x_pos - 1)
elif c == curses.KEY_RIGHT:
x_pos = min(2, x_pos + 1)
elif c == ord('q') or c == ord('Q'):
break
elif c == ord(' '):
# Update
y, x = stdscr.getyx()
if stdscr.inch(y, x) != ord(' '):
continue
draw(y, x, stdscr, player_id)
board[y_pos][x_pos] = CH_P2 if player_id else CH_P1
if check_victory(board, y_pos, x_pos):
stdscr.addstr(Y_OFFSET + 9, 0, 'Player {} wins'.format(
CH_P2 if player_id else CH_P1))
break
# Switch player
player_id = (player_id + 1) % 2
print_players(stdscr, player_id)
stdscr.refresh()
stdscr.getkey()
if __name__ == '__main__':
curses.wrapper(main)
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.
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], ' ')
I'm doing a mini-project on Coursera and I can run most parts of my code. However there's an error in the critical part about the game's match or not checking.
# implementation of card game - Memory
import simplegui
import random
# helper function to initialize globals
def new_game():
global turns, state, pairs, cards
turns = 0
state = 0
pairs = []
cards = range(9) * 2
random.shuffle(cards)
# define event handlers
def mouseclick(pos):
# add game state logic here
global turns, state, pairs
pointed = pos[0] // 50
if pointed in pairs:
pass
else:
if state == 0:
state = 1
pairs.append(pointed)
elif state == 1:
state = 2
turns += 1
label.set_text('Turns =' + str(turns))
pairs.append(pointed)
# if cards[pairs[-2]] == cards[[pairs[-1]]:
# flag = True
# else:
# flag = False
else:
state = 1
if flag == False:
del pairs[-2:]
pairs.append(pointed)
# cards are logically 50x100 pixels in size
def draw(canvas):
for n in range(1, 16):
canvas.draw_line((n * 50, 0), (n * 50, 100), 1, 'Green')
for n in pairs:
canvas.draw_line((n * 50 + 25, 0), (n * 50 + 25, 100), 50, 'White')
for n in pairs:
canvas.draw_text(str(cards[n]), (n * 50 + 15, 65), 50, 'Black')
# create frame and add a button and labels
frame = simplegui.create_frame("Memory", 800, 100)
frame.set_canvas_background('Red')
frame.add_button("Reset", new_game)
label = frame.add_label("Turns = 0")
# register event handlers
frame.set_mouseclick_handler(mouseclick)
frame.set_draw_handler(draw)
# get things rolling
new_game()
frame.start()
# Always remember to review the grading rubric
I commented out Line 31 to 34 and that's the part where I have a problem. The console keeps telling me Line 31: SyntaxError: bad input (' ') but I think the indentation is correctly made.
Please help me figure out why it's a 'bad input', thanks a lot!
Update:
Thanks to Russell's help, this function works now.
# define event handlers
def mouseclick(pos):
# add game state logic here
global turns, state, pairs, flag
pointed = pos[0] // 50
if pointed in pairs:
pass
else:
if state == 0:
state = 1
pairs.append(pointed)
elif state == 1:
state = 2
turns += 1
label.set_text('Turns =' + str(turns))
pairs.append(pointed)
if cards[pairs[-2]] == cards[pairs[-1]]:
flag = True
else:
flag = False
else:
state = 1
if flag == False:
del pairs[-2:]
pairs.append(pointed)
Your if statement is indented too far.
elif state == 1:
state = 2
turns += 1
label.set_text('Turns =' + str(turns))
pairs.append(pointed)
if cards[pairs[-2]] == cards[pairs[-1]]:
flag = True
else:
flag = False
else:
state = 1
if flag == False:
del pairs[-2:]
pairs.append(pointed)