Attempting to Undraw in my GUI Python Game - python

I'm creating a Memory Matching game for a final project for my compsci class.
As of now, I have the cards all appear on the GUI window once you hit start game.
Once start game is hit, all the cards with their face value shows with the back of the card immediately. (So you never actually see the card fronts)
My reasoning for doing this is so that when you click on a card, I'll simply undraw the back card image instead of "Flipping" anything.
However, I keep getting errors, and when I don't get errors, it simply results in my program saying "Not Responding" and makes me have to restart the Shell.
Here are some little bits and pieces of my code which I think pertain to my issue:
for firstcard in range(6):
firstrow = self.deck.dealCard()
randomsuite = firstrow.getSuite()
randomrank = firstrow.getRank()
#Real image with face value of card
realCard = Image(Point(xpos,ypos),"playingcards/"+ (randomsuite) + str(randomrank) +".gif")
realCard.draw(win)
#Red Back of card to cover image
firstcard = Image(Point(xpos,ypos),"playingcards/b1fv.gif")
firstcard.draw(win)
#pushes the card to the right a bit
xpos += 100
while not Quitbutton.isClicked(p):
#Start Game
if StartGameButton.isClicked(p) and player == True:
if first == True:
Game.gameboard(win,150,125)
firstcard = Image(Point(xpos,ypos),"playingcards/b1fv.gif")
first = False
if StartGameButton.isClicked(p):
p = win.getMouse()
if firstcard.isClicked(p):
firstcard.undraw()
p = win.getMouse()
As of now you can see I have in my code if firstcard.isClicked(p):. However, this doesn't actually work because my isClicked function is a part of a Button Class and therefore, only works when dealing with Buttons and not images. So I'm not entirely sure what to do to select a single card and how to show that that card has been clicked and therefore should be undrawn

Related

Python Tkinter Tic Tac Toe AI

I am trying to make a Tic Tac Toe in tkinter however I am running into some problems with the AI system. What I'm trying to do is that if the middle spot isn't taken it will chose it and if it isn't it will pick a random number and map out all the routes it can take to win and all the routes the player will use and for it to block them however I am running into this problem. My code:
def click1():
if isTaken1 == False:
Button1.config(text = "O")
pTurn1 = True
Button1 = Button(root, command = click1)
Button1.config(width = "5", height = "3")
Button1.place(x = 100, y = 30)
#I have nine of these however I can't show them all as it will make this post very long
I am trying to add it when the player takes a turn (The pTurn variable) it will make the AI act however, I have no idea where to put the AI code.
I am trying to do something like:
If isTaken5 == False: #Checking if the middle spot is taken
Button5.config(text = "X") #Player is O and AI is X
else:
AIChoice = random.randint(1,8)
if AIChoice == 1:
Button1.config(text = "X")
So you get the basic idea for it, but I have no idea where to put the cod as if statements put after where you change it don't work.
In a turn-based game, you can call the AI function immediately after the user takes their turn. For example, let's start with a function for the computer's turn. This is where your ai exists:
def computer_turn():
<your logic to pick an empty square>
Ideally you'll also want to check for the case where the computer picked the last place, but I've left that out now to keep the example simple.
Next, we have a function for the player's turn. In this example, it takes a row and column that was clicked on. This will select the button that was clicked, check to see if the game is over, and call computer_turn if the game isn't over yet.
It would look something like this:
def player_turn(row, column):
<your logic to select the given row and column>
if not is_game_over():
computer_turn()
This isn't the only way to handle the game logic. You could create a small state machine, for example. However, for a game as simple as tic-tac-toe, this turn-based system is good enough.

can't figure out a loop with some conditions

I'm starting to learn programming and trying to write my first flash game bot, but I think I can't sort things out
This game is, player click in 5 areas randomly, if player is lucky, the enemy will get shot and reduce his hp. Enemy's hp is 6, and this game requires player to finish this in no more than 7 shots, which means player has only one chance to miss the guess.
So I "cut" the HP bar into 6 jugdement areas, and use PIL in python to judge the pixel's color change in every area, then let pyautogui to do some auto clicks. Main part of this code is:
while True:
flag = 1
for i in range(6):
s = screenGrab()
pixels = s.load()
pixelJugde_1 = pixels[judgeAreas[i]] # jugde if hp is reduced after this shot
if pixelJugde_1 != (0, 0, 0): # if this shot missed
randomClick() # try again
s = screenGrab()
pixels = s.load()
pixelJugde_2 = pixels[judgeAreas[i]] # second judge of this shot
if (pixelJugde_2 != pixelJugde_1): # hp changed, second try didn't miss
flag = 1 # mark this shot has been tried twice
randomClick() # continue next shot
elif (pixelJugde_2 == pixelJugde_1 and flag == 1): # second try missed
resetResult() # restart the game
break
else:
print 'got shot' # success at first try
randomClick() # next shot
now my problem is, if the first shot has been tried twice and marked, when the next shot begins and misses, it will still try twice, just like the marking flag is not working. So how to fix this?

Modifying a dictionary inside of an if statement

I've been trying to make a basic text game in Python, and I'm using dictionaries to contain the player's information. I want to make it so that when a player's health reaches 0, the code will stop running. I've had trouble making that happen. My dictionary, which is at the beginning of my code, looks like this:
playerAtt = {}
playerAtt["Weapon"] = "Baseball bat"
playerAtt["Party"] = "Empty"
playerAtt["Health"] = 15
playerAtt["Cash"] = "$100"
print(playerAtt)
if playerAtt['Health'] <= 0:
exit()
The bottom section is what I wrote to try and make the code stop running when the player's health reached zero, but it doesn't seem to work. In one path of my game, your health gets set to zero and the game is supposed to end, but the program continues to run:
townChoice = raw_input("You met a traveler in the town. 'Yo. I'm Bob. Let's be friends.' Will you invite him to your party? Y/N\n")
if townChoice == 'y' or townChoice == 'Y':
print("That kind traveler was not such a kind traveler. He stabbed you with a machete. RIP " + Name + '.')
playerAtt['Health'] == 0
When you reach this part of the game, all it does is print the message, and moves on to the next decision. In this situation, I could just manually end the program by doing exit() under the print command, but there are circumstances where the player only loses a fraction of their health, and they would eventually reach zero. Sorry if this is a stupid question, I've only been working on Python for a few days.
You have two "=" when you set the player's health to 0
I had put 2 == instead of 1 = when defining
playerAtt["Health"].
Also, I needed to make sure it was constantly checking if the player's health was zero, so I used a while loop. I used
while playerAtt["Health"] = 0:
deathmsg()
exit()
to fix it. deathMsg was a function I made to display a random death message, for more information.

How to display text for only a certain amount of time?

I'm looking to display a message on the screen when a player wins, and get the text to display for 5 seconds, and then go back to the main menu start screen. Using the time.delay function however, my screen pauses and then displays the text in a flash, but then immediately goes to the startscreen. Is there a more efficient way of getting the text to be displayed for long enough to be read?
Below is the function I use to actually display the message:
def winnerPlayerOne():
screen.fill(PINK)
winnerP1Message = winnerFont.render("Congrats Player 1. You Win!", True, WHITE)
screen.blit(winnerP1Message, ((400 - (winnerP1Message.get_width()/2)),(300 - (winnerP1Message.get_height()/2))))
pygame.display.update()
pygame.time.delay(5000)
startscreen()
And below this is how I call this function, within the main loop:
if playeroneScore == 5:
winnerPlayerOne()
if playertwoScore == 5:
winnerPlayerTwo()
Any help would be greatly appreciated!
Benjamin's answer probably will work fine in your case. But if you want something that doesn't interfere with your game's visuals, I would consider setting a timer like so...
WITHIN GAME LOOP:
if gameWonScreen:
screen.fill(PINK)
winnerP1Message = winnerFont.render("Congrats Player 1. You Win!", True, WHITE)
screen.blit(winnerP1Message, ((400 - (winnerP1Message.get_width()/2)),(300 - (winnerP1Message.get_height()/2))))
timer = timer + elapsed/1000
elapsed = fpsClock.tick(FPS)
if timer > timeWinScreen:
gameWonScreen = false
Initialize 'timeWinScreen' to the desired message duration at the start of the application and set 'timer' to '0' and gameWonScreen to 'true' when the player wins. Using elapsed = fpsClock.tick(FPS) will hold the time value since the last tick. You don't need to use it for this process (you could just use a fraction of your FPS) but using 'elapsed' is good practice because it helps with smoothing animations of certain objects.
Try out pygame.time.wait(5000). It should behave more in the way you are expecting. It does prevent any code running in the background as well, but that didn't seem like it would be an issue for your use case.
Try this:
Remember that in the class below, time is not the way you measure time in pygame. It is the number of loop happened in the main loop.
class disp_txt:
def __init__(self,text,time,destination):
self.text = text
self.time = time
self.destination = destination
self.shfnt = pygame.font.SysFont("comicsens",30,False)
self.shtxt = self.shfnt.render(self.text,0,(255,0,0))
def show(self,surface):
if self.time>0:
surface.blit(self.shtxt,self.destination)
self.time -= 1
hint = disp_txt("text",100,(100,400)) #example
hint.show(screen) #in the main loop or where you are drawing

Python tkinter for loop not displaying correcty

Making a blackjack game and this for loop is not printing the correct cards. It prints the first card and second card fine, but when it gets to the third card it reprints the first card instead in the third one's place. I have tried both deleting and not deleting the images before print but it doesn't work out.
if len(playerCards) > 0:
for i in range(len(playerCards)):
#print(currentHand[i])
#print currentHand
#print(i)
#print(playerCards[i])
GAME_CANVAS._tkcanvas.delete("pCard" + str(i))
GAME_CANVAS._tkcanvas.create_image(125+((i-1)*80), 75, image = playerCards[i].image, tag = "pCard" + str(i))
I have the current print statements commented because they should not affect the code in any way.

Categories

Resources