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)
Related
I am rather new to python and am attempting to create a terminal based minesweeper clone. Everything has been going well other than implementing the flood fill algorithm. Whenever I run the flood fill it just gets stuck looping indefinitely. If anyone could help with this it would be greatly appreciated.
import random
from queue import Queue
'⚑'
fieldY = 10
fieldX = 5
validFloodFills = ['1','2','3','4','5','6','7','8','◼']
visibleField = []
internalField = []
#creates blank fields with the ◼ character
def generateField(grid, y , x):
for i in range(y):
tempList = []
for i in range(x):
tempList.append("◼")
grid.append(tempList)
#places bombs into the internal field according to the numOfBombs argument
def placeBombs(numOfBombs):
generateField(internalField, fieldY, fieldX)
placed = 0
#while loop is use becuase you cannot step an iter back with a for loop
while placed != numOfBombs:
y = random.randint(0, fieldY-1)
x = random.randint(0, fieldX-1)
if internalField[y][x] == 'X':
continue
else:
internalField[y][x] = 'X'
placed += 1
#loops through all tiles and numbers them according to the number of adjacent bombs
def placeInternalNumbers():
global fieldY
global fieldX
#loop through all tiles and check all 8 neighbours
#if neighbour is a bomb then add 1 to int
#after checking all neighbours the value of that int is assigned to that tile
for idxY, y in enumerate(internalField):
for idxX, x in enumerate(y):
#makes indexes in range
fieldY -= 1
fieldX -= 1
idxY -= 1
idxX -= 1
adjacentBomb = 0
if internalField[idxY][idxX] == 'X':
continue
#look down one
if idxY != fieldY:
if internalField[idxY+1][idxX] == 'X':
adjacentBomb += 1
#look up one
if idxY != 0:
if internalField[idxY-1][idxX] == 'X':
adjacentBomb += 1
#look right one
if idxX != fieldX:
if internalField[idxY][idxX+1] == 'X':
adjacentBomb += 1
#look left one
if idxX != 0:
if internalField[idxY][idxX-1] == 'X':
adjacentBomb += 1
#look down right
if idxY != fieldY and idxX != fieldX:
if internalField[idxY+1][idxX+1] == 'X':
adjacentBomb += 1
#look down left
if idxY != fieldY and idxX != 0:
if internalField[idxY+1][idxX-1] == 'X':
adjacentBomb += 1
#look up right
if idxY != 0 and idxX != fieldX:
if internalField[idxY-1][idxX+1] == 'X':
adjacentBomb += 1
#look up left
if idxY != 0 and idxX != 0:
if internalField[idxY-1][idxX-1] == 'X':
adjacentBomb += 1
#checks if the adjacent bombs are zero and does not update the tile if there are no adjacent bombs
if adjacentBomb == 0:
continue
internalField[idxY][idxX] = str(adjacentBomb)
#prints the field parsed to the function
def printField(field):
for i in field:
print(i)
#floodFill
def floodFill(y, x):
#TODO needs to read and compare with the internal board and then write changes to the visible board
n = len(visibleField)
m = len(visibleField[0])
if y < 0 or y >= n or x < 0 or x >= m or internalField[y][x] not in validFloodFills:
return
else:
visibleField[y][x] = internalField[y][x]
floodFill(y+1, x)
floodFill(y-1, x)
floodFill(y, x+1)
floodFill(y, x-1)
#main loop
def mainLoop():
cont = True
while cont:
printField(visibleField)
print()
printField(internalField)
print("To select a tile type 'S' then the x coordinate and y coordinate all seperated by spaces\nTo flag a tile type 'F' then the x coordinate and y coordinate all seperated by spaces")
select = input().split(' ') #TODO input validation, use length to check for multiple spaces
operator = select[0]
x = int(select[1])
y = int(select[2])
if operator == 'S':
if internalField[y][x] == 'X':
break
else:
floodFill(y, x)
continue
elif operator == 'F':
pass
#TODO more stuff on fail eg printing revealed minefield
print("You hit a bomb, better luck next time")
generateField(visibleField, fieldY, fieldX)
placeBombs(5)
placeInternalNumbers()
mainLoop()
printField(visibleField)
print()
printField(internalField)
When I put the snake to start going to the "►" direction, it goes faster than when I do it for "◄" and the same result for "▲" and "▼".
Actually, it literally teleports. Even if I see that it's doing the right way correctly by going from key to key.
Maybe it's doing the process without showing it, until the end.
Do you see any reasons why does that happen? Because I really don't see why.
import numpy as np
from random import randint
import keyboard
from time import sleep
import os
#Get to work
game_area = {}
#Random snake and apple start positions
apple = randint(0, 540)
snake_pos = randint(0, 540)
#Define positions
for x in np.arange(0,540,1):
game_area[x] = '.'
#Insert Apple
game_area[apple] = 'Ó'
#Limit areas
game_area[0], game_area[59], game_area[60], game_area[119],game_area[120], game_area[179],game_area[180], game_area[239],game_area[240],game_area[299],game_area[300],game_area[359], game_area[360],game_area[419],game_area[420],game_area[479],game_area[480], game_area[539] = '╔','╗','║','║','║','║','║','║','║','║','║','║','║','║','║','║','╚','╝'
for x in range(1,59):
game_area[x] = '═'
for x in range(481,539):
game_area[x] = '═'
#Snake Class
class Snake:
def __init__(self, length, position):
self.length = length
self.position = position
def printar(self):
print(self.length,self.position)
snake = Snake(1,snake_pos)
game_area[snake.position] = '►'
#Functions
def prepare_game():
#Create game area
for number, instance in zip(list(game_area.keys()), list(game_area.values())):
if number not in [60,120,180,240,300,360,420,480]:
print(instance, end='')
else:
print('\n' + instance, end='')
print('')
def start_game():
global game_area
game_over = False
while True:
prepare_game()
if game_over == False:
#Keyboard Detect / Automatic Move
if '◄' in list(game_area.values()):
for x,y in game_area.items():
if y == '◄':
if game_area[x - 1] != '║':
game_area[x - 1] = y
game_area[x] = ' '
else:
game_over = True
break
if '►' in list(game_area.values()):
for x,y in game_area.items():
if y == '►':
if game_area[x + 1] != '║':
game_area[x + 1] = y
game_area[x] = ' '
else:
game_over = True
break
if '▲' in list(game_area.values()):
for x,y in game_area.items():
if y == '▲':
if game_area[x - 60] != '═':
game_area[x - 60] = y
game_area[x] = ' '
else:
game_over = True
break
if '▼' in list(game_area.values()):
for x,y in game_area.items():
if y == '▼':
if game_area[x + 60] != '═':
game_area[x + 60] = y
game_area[x] = ' '
else:
game_over = True
break
if keyboard.is_pressed('up arrow'):
pass
if keyboard.is_pressed('left arrow'):
pass
if keyboard.is_pressed('right arrow'):
pass
if keyboard.is_pressed('down arrow'):
pass
if keyboard.is_pressed('space'):
break
#End
sleep(1)
os.system("cls")
continue
else:
break
start_game()
I have an excercise to do and I'm stuck. It's the board game Alak, not much known, that I have to code in python. I can link the execrcise with the rules so you can help me better. The code has the main part and the library with all the procedures and function.
from Library_alak import *
n = 0
while n < 1:
n = int(input('Saisir nombre de case strictement positif : '))
loop = True
player = 1
player2 = 2
removed = [-1]
board = newboard(n)
display(board, n)
while loop:
i = select(board, n, player, removed)
print(i)
board = put(board, player, i)
display(board, n)
capture(board, n, player, player2)
loop = True if again(board, n, player, removed) is True else False
if player == 1 and loop:
player, player2 = 2, 1
elif player == 2 and loop:
player, player2 = 1, 2
win(board, n)
print(win(board, n))
And here is the library:
def newboard(n):
board = ([0] * n)
return board
def display(board, n):
for i in range(n):
if board[i] == 1:
print('X', end=' ')
elif board[i] == 2:
print('O', end=' ')
else:
print(' . ', end=' ')
def capture(board, n, player, player2):
for place in range(n):
if place == player:
place_beginning = place
while board[place] != player:
place_end = place
if board[place + x] == player:
return board
else:
return board
def again(board, n, player, removed):
for p in board(0):
if p == 0:
if p not in removed:
return True
else:
return False
def possible(n, removed, player, i, board):
for p in range(n + 1):
if p == 1:
if board[p-1] == 0:
if p not in removed:
return True
else:
return False
def win(board, n):
piecesp1 = 0
piecesp2 = 0
for i in board(0):
if i == 1:
piecesp1 += 1
else:
piecesp2 += 1
if piecesp1 > piecesp2:
print('Victory : Player 1')
elif piecesp2 > piecesp1:
print('Victory : Player 2')
else:
return 'Equality'
def select(board, n, player, removed):
loop = True
while loop:
print('player', player)
i = int(input('Enter number of boxes : '))
loop = False if possible(n, removed, player, i, board)is True else True
return i
def put(board, player, i):
i -= 1
if board[i] == 0:
if player == 1:
board[i] = 1
return board
else:
board[i] = 2
return board
else:
put(board, player, i)
So my problems here are that I have few errors, the first one is that when I enter the number '1' when asked to enter a number of boxes ( which is the place to play on ) nothing happens. Then when entering any other number, either the error is : if board[place + x] == player:
NameError: name 'x' is not defined
or there seems to be a problem with the : if board[place + x] == player:
NameError: name 'x' is not defined
I would appreciate a lot if anyone could help me. I'm conscious that it might not be as detailed as it should be and that you maybe don't get it all but you can contact me for more.
Rules of the Alak game:
Black and white take turns placing stones on the line. Unlike Go, this placement is compulsory if a move is available; if no move is possible, the game is over.
No stone may be placed in a location occupied by another stone, or in a location where a stone of your own colour has just been removed. The latter condition keeps the game from entering a neverending loop of stone placement and capture, known in Go as ko.
If placing a stone causes one or two groups of enemy stones to no longer have any adjacent empty spaces--liberties, as in Go--then those stones are removed. As the above rule states, the opponent may not play in those locations on their following turn.
If placing a stone causes one or two groups of your own colour to no longer have any liberties, the stones are not suicided, but instead are safe and not removed from play.
You shouldn't use "player2" as a variable, there's an easier way, just use "player" which take the value 1 or 2 according to the player. You know, something like that : player = 1 if x%2==0 else 2
and x is just a increasing int from 0 until the end of the game.
Ok I have a feeling that this is a simple simple issue but I have been staring at this code for about 10 hours now.
The issue I am having is in mastermind is that once I get it to recognize that I have the correct colors in the right spot I can get it to display the right spots with X and the wrong spots with O. I need to be able to convert that so instead of X and O I need it to tell the user that he/she has 2 blacks and one white
For example: The secret code is RGYB The user enters RGOY so then Python relays "You have 2 blacks(The R and G spots) and one 1 White (The Y because it's the right color just in the wrong index) As of right now I got it to display X for the right color in the right spot and anything else it is an O
I will post what I have been working with now but today I am at my wit's end
https://pastebin.com/HKK0T7bQ
if correctColor != "XXXX":
for i in range(4):
if guess[i] == tempCode[i]:
correctColor += "X"
if guess[i] != tempCode[i] in tempCode:
correctColor += "O"
print (correctColor + "\n")
if correctColor == "XXXX":
if attempts == 1:
print ("You think you are sweet because you got it right on the first try? Play me again!")
else:
print ("Well done... You needed " + str(attempts) + " attempts to guess.")
game = False
A few comments
X and O
you use X and 0 to denote the success, it will be easier and faster to use a list or tuple or booleans for this, that way you can use sum() to count how many colors and locations were correct. Then whether you represent that with X and O or red and white pins is a matter for later
compartmentalization
Your game logic (guess input, input validation, do you want to continue, etc) is mixed with the comparison logic, so it would be best to separate the different functions of your program into different methods.
This is an fineexample to introduce object oriented programming, but is so simple it doesn't need OO, but it can help. What you need is a method which takes a series of colours and compares it to another series of colours
Standard library
Python has a very extended standard library, so a lot of stuff you want to do probably already exists
Correct colours
to count the number of letters which occur in 2 strings, you can use collections.Counter
guess = "RGOY "
solution = "RGYB"
a = collections.Counter(guess)
b = collections.Counter(solution)
a & b
Counter({'G': 1, 'R': 1, 'Y': 1})
correct_colours = sum((a & b).values())
3
So the user guessed 3 colours correctly
Correct locations
can be solved with an easy list comprehension
[g == s for g, s in zip(guess, solution)]
[True, True, False, False]
sum(g == s for g, s in zip(guess, solution))
2
so the used put 2 colours on the correct location
This is a MasterMind I made in Python. Hope you like it and it helped you! :)
import random
import time
from tkinter import *
def select_level():
global level
level = level_selector.get()
root.destroy()
root = Tk()
level_selector = Scale(root, from_=1, to=3, tickinterval=1)
level_selector.set(0)
level_selector.pack()
Button(root, text="Select a difficulty level", command=select_level).pack()
mainloop()
cpc_1_digit = 0
cpc_2_digit = 0
cpc_3_digit = 0
cpc_4_digit = 0
p_1_digit = 0
p_2_digit = 0
p_3_digit = 0
p_4_digit = 0
correct_correct = 0
correct_wrong = 0
chances = 0
if level == 1:
chances = 15
elif level == 2:
chances = 10
else:
chances = 7
cpc_1_digit = random.randint(0, 9)
while cpc_2_digit == cpc_1_digit or cpc_2_digit == cpc_3_digit or cpc_2_digit ==
cpc_4_digit:
cpc_2_digit = random.randint(0, 9)
while cpc_3_digit == cpc_1_digit or cpc_3_digit == cpc_2_digit or cpc_3_digit ==
cpc_4_digit:
cpc_3_digit = random.randint(0, 9)
while cpc_4_digit == cpc_1_digit or cpc_4_digit == cpc_2_digit or cpc_4_digit ==
cpc_3_digit:
cpc_4_digit = random.randint(0, 9)
while chances > 0:
correct_correct = 0
correct_wrong = 0
answer = input("Enter a four-digit number with different digits (e.g 1476): ")
p_1_digit = int(answer[0])
p_2_digit = int(answer[1])
p_3_digit = int(answer[2])
p_4_digit = int(answer[3])
if p_1_digit == cpc_1_digit:
correct_correct = int(correct_correct) + 1
elif p_1_digit == cpc_2_digit or p_1_digit == cpc_3_digit or p_1_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_2_digit == cpc_2_digit:
correct_correct = correct_correct + 1
elif p_2_digit == cpc_1_digit or p_2_digit == cpc_3_digit or p_2_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_3_digit == cpc_3_digit:
correct_correct = int(correct_correct) + 1
elif p_3_digit == cpc_1_digit or p_3_digit == cpc_2_digit or p_3_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_4_digit == cpc_4_digit:
correct_correct = int(correct_correct) + 1
elif p_4_digit == cpc_1_digit or p_4_digit == cpc_3_digit or p_4_digit ==
cpc_2_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
print("")
if int(correct_correct) == 4:
print("Congratsulations! You found the computer's number!")
break
elif int(correct_wrong) > 0 or int(correct_correct) >= 1 and int(correct_correct)
< 4:
print("You got " + str(correct_correct) + " correct digit(s) in the correct
place, and " + str(correct_wrong) + " correct digit(s) but in wrong place.")
elif int(correct_correct) == 0 and int(correct_wrong) == 0:
print("You didn't guess any number, try again!")
else:
raise Exception("CheckError: line 69, something went wrong with the
comparings.")
exit()
print("")
chances = chances - 1
if chances == 0:
print("You lost... The secret number was " + str(cpc_1_digit) + str(cpc_2_digit)
+ str(cpc_3_digit) + str(cpc_4_digit) + ". Try again by rerunning the program.")
time.sleep(4)
this is the main code:
import MainMod
print("Welcome!")
print("Note: In this games you use wasd+enter to move!\nYou press 1 key and then enter,if you press multiple kets it wont work.\nYou will always move by 5 meters.")
CurrentRoom = 1
#Limits work this way!1st and 2nd number are X values(1st is <---- limit,2nd is ---> limit)
#3rd and 4th are y values(1st is v limit,2nd is ^ limit)
# X and Y are coordinates; 0,0 is the starting point of every room
while True:
if CurrentRoom ==1:
print("This is room 1")
MainMod.roomlimits = [-15 , 15, -15 , 15]
MainMod.doorloc1 = [-15,10,15]
MainMod.doorloc2 = [15,-2,2]
while CurrentRoom == 1:
MainMod.MainLel()
if MainMod.door1 == 1:
print("DAMN SON")
CurrentRoom = 2
break
elif MainMod.door2 == 1:
print("Plz no")
CurrentRoom = 3
break
while CurrentRoom == 2:
MainMod.MainLel()
and this is the MainMod module is :
x = 0
y = 0
roomlimits = 0
doorloc1=0
doorloc2=0
door1 = 0
door2 = 0
direct = 0
def MainLel():
global direct
movementinput()
movement(direct)
doorcheck()
def movement(dir):
global x,y,roomlimits,door1,door2,doorloc1,doorloc2
if dir == "w":
y += 5
if y > roomlimits[3]:
y = roomlimits[3]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "s":
y -= 5
if y < roomlimits[2]:
y = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "d":
x += 5
if x > roomlimits[1]:
x = roomlimits[1]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "a":
x -= 5
if x < roomlimits[0]:
x = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
def movementinput():
global direct
while True:
direct = input("")
if direct in ("w","a","s","d","W","A","D","S"):
break
else:
print("You failure.")
def doorcheck():
global x,y,doorloc1,doorloc2,door1,door2
if x == doorloc1[0] and doorloc1[1] <= y <= doorloc1[2]:
door1 = 1
elif y == doorloc2[0] and doorloc2[1] <= x <= doorloc2[2]:
door2 = 1
else:
door1,door2 = 0,0
Im using a module instead of classes because i dont know how to use classes yet,anyways,what happens in the program is that if i am in the door location,it simply prints "DAMN SON" and doesnt break out of the Room loop,any help? EDIT NOTE: I added the break statement later on to try if it would help,sadly it didnt,i am also a bit tired so im guessing i made a logic mistake somewhere,thanks in advance for help.
Final edit: The code was functional all along,i was just testing it incorrectly!Thanks for the awnsers,ill close this question now.
Since I could not imagine it didn't work, I added two markers (print commands), to room 1 and 2:
while CurrentRoom == 1:
print("one")
mod.MainLel()
and
while CurrentRoom == 2:
print("two")
mod.MainLel()
This is what happened:
Youre current coordinates are x: -5 y: 15
one
a
Youre current coordinates are x: -10 y: 15
one
a
Youre current coordinates are x: -15 y: 15
DAMN SON
two
a
Youre current coordinates are x: -15 y: 15
two
It turned out to be working fine. The break is redundant however. The loop will break anyway, since the condition becomes False.