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.
Related
I want to create a battleship AI guessing, where the AI takes random shots until a hit is made.
Once a hit is made, the AI will guess the surrounding coordinates until the orientation of the ship is established.
Once the orientation is known, the AI will guess either side of the hits until the ship is sunk. It will then return to random guessing.
This page under 'a better strategy' explains more of what I want to do but improved so the AI will recognise the orientation.
The code below shows the random guessing currently used:
def ai_guessing():
global player_ships_guessed
while True:
guess_x = random_x()
guess_y = random_y()
# if statement ensuring no guesses are repeated
if playerBoard[guess_x][guess_y] == "O" or playerBoard[guess_x][guess_y] == "S":
break
guess = str(guess_x)+str(guess_y)
What is the best approach to this?
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.
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
This program is supposed to play the card game War. Okay so I need to be able to prompt the user to keep playing and have them respond by hitting the enter key. I'm not sure how to make this happen. Help?
import cards
# Create a deck of cards
the_deck = cards.Deck()
# Shuffle the deck, then display it in 13 columns
the_deck.shuffle()
print( "===== shuffled deck =====" )
the_deck.display()
def main():
'''This function deals out half the deck to each
player. It sorts the rank so as to solve the problem
with Aces causing an infinite game'''
player1_list=[]
player2_list=[]
for i in range( 26 ):
p1_temp= the_deck.deal()
player1_list.append( p1_temp )
p2_temp= the_deck.deal()
if (p2_temp.rank()==1):
player1_list.append(p2_temp)
player2_list.append(player1_list.pop(0))
else:
player2_list.append(p2_temp)
print()
# Card dealt to Player #1
player1_card = player1_list.pop( 0 )
print( "===== player #1 =====" )
print( "Card dealt to player #1:", player1_card )
print( player1_list )
print()
#Card dealt to Player #2
player2_card=player2_list.pop(0)
print( "===== player #2 =====" )
print("Card dealt to player #2:",player2_card)
print( player2_list )
# Compare the two cards using overloaded operators
print()
if player1_card == player2_card:
print( "Tie:", player1_card, "and", player2_card, "of equal rank" )
elif player1_card > player2_card:
print("Player #1 wins:",player1_card,"of higher rank than",player2_card)
else:
print("Player #2 wins:",player2_card,"of higher rank than",player1_card)
print()
main()
def keep_playing():
'''Determines whether the player wants to continue. If so they press the
Enter key and the function calls main to start all over.'''
still_playing=input('Press "Enter" to continue playing')
Enter=1
while still_playing==Enter:
main()
keep_playing()
Assuming the rest of your main is working (and the imported Deck class): your two main problems are you forgot to call your main and the method you are using to test the variable Enter. Since your taking an input for Enter you just need to test this against an empty string or just test that it is empty - as input strips newlines by default.
def play_hand():
print ("all the play code goes here")
#just a simple exit here no return needed
'''This function deals out half the deck to each
player. It sorts the rank so as to solve the problem
with Aces causing an infinite game
player1_list=[]
player2_list=[] ... etc ...'''
def keep_playing():
'''Determines whether the player wants to continue. If so they press the
Enter key and the function calls main to start all over.'''
return input('Press "Enter" to continue playing')
def main():
# the_deck = Card.Deck() # create deck instance (depending on how shuffle method is written this may need to go in while loop)
still_playing = "" #Set still_playing to empty string to more easily use input
while not still_playing: #this will keep going as long as still_playing is an empty string
print("hello main") # cause it fun :) - also as you can put an intro here or the shuffle so:
# the_deck.shuffle()
# print( "===== shuffled deck =====" )
# the_deck.display()
play_hand()
# Do all your other stuff here
still_playing = keep_playing() #Calls the function and stores returned value (can do this with just input but using return to show an option)
main()
As a secondary note, you need to learn how to isolate the problem within your code. To that end: the following shows a testable instance (and solution) of the enter to continue problem your having. Run this and it will only test (in this case solve) the enter problem, this is what Stack Overflow means by a minimal, complete, verifiable example.
As #IanAuld mentioned, you have not called your Keep_playing() function anywhere. Instead of calling main(), simply call Keep_playing(). If you'd like to just start the game without the "Press Enter to continue playing," just make the first line of the Keep_playing() function a call to main(), so that it runs and then keeps checking if the user wants to continue.
Also, you have an infinite loop in Keep_playing(). Put the input(...) part inside the while loop after you call main(). That way, it will reprompt every loop and change the still_playing variable.
It should look like this:
def keep_playing():
'''Determines whether the player wants to continue. If so they press the
Enter key and the function calls main to start all over.'''
still_playing=""
Enter=""
while still_playing==Enter:
main()
still_playing=input('Press "Enter" to continue playing')
keep_playing()
You can read this SO question to figure out how to implement reading the "enter" key as input (it's quite simple, so don't worry)
Additionally, as a good practice in Python (and most other languages), make variables and function names lowercase, as uppercase names are typically reserved for class use. Even if this isn't going to be spread or maintained around, it's good to get into the habit.
I'm writing a program for my physics final. Throughout the semester we have used vPython to model situations and get exact answers, etc. Our final project is to create a game using vPython that includes some type of physics.
I chose to remake Bowman except with tanks. So you have a tank on the right hand of the screen and left hand of the screen with a wall in the middle. The object is to aim your cannon and shoot the right velocity to hit your opponent's tank. I have the a good chunk of the program complete however I am stuck on a few different things.
First, how can I time a keystroke? I have it so I shoot from the each cannon however I want to be able to hold down a key and dependent on how long it's held down for the faster the initial velocity will be.
Second, where would I incorporate gravity into the program? I have a general idea of how to but I just don't know which function to put it into.
Lastly, I have a wall height being generated randomly each time the program is run. However sometimes the wall is so small you can't see it. Is there a way I can set a range of values for this?
Here is my code:
from visual import*
from random import*
scene.autoscale=False
scene.width = 1500
scene.height = 800
scene.title='Tanks'
def moveaup(gun):
theta=arctan(gun.axis.y/gun.axis.x)
dtheta=.1
if (theta<pi/2):
theta=theta+dtheta
if not (theta>pi/2):
gun.axis=(cos(theta),sin(theta),0)
else:
gun.axis=vector(0,1,0)
def moveadown(gun):
theta=arctan(gun.axis.y/gun.axis.x)
dtheta=.1
if (theta>0):
theta=theta-dtheta
gun.axis=(cos(theta),sin(theta),0)
def movebup(gun):
theta=arctan(gun.axis.y/gun.axis.x)+pi
dtheta=.1
if (theta>pi/2):
theta=theta-dtheta
if not (theta<pi/2):
gun.axis=(cos(theta),sin(theta),0)
else:
gun.axis=vector(0,1,0)
def movebdown(gun):
theta=arctan(gun.axis.y/gun.axis.x)+pi
dtheta=.1
if (theta<pi):
theta=theta+dtheta
gun.axis=(cos(theta),sin(theta),0)
def shoota(gun):
vel = vector(1,1,0)
bullet = sphere(pos=(gun.pos.x+gun.axis.x,gun.pos.y+gun.axis.y,0),radius=(.0785),color=color.yellow)
bullet.v = vector(0,0,0)
bullet.v = bullet.v+vel
bulletlist.append(bullet)
def shootb(gun):
vel = vector(-1,1,0)
bullet = sphere(pos=(gun.pos.x+gun.axis.x,gun.pos.y+gun.axis.y,0),radius=(.0785),color=color.green)
bullet.v = vector(0,0,0)
bullet.v = bullet.v+vel
bulletlist.append(bullet)
def bulletlistupdate(bulletlist):
dt=.01
for a in bulletlist:
a.pos=a.pos+a.v*dt
def checks(agun,bgun):
if scene.kb.keys:
key=scene.kb.getkey()
if key=='a':
moveaup(agun)
if key=='s':
moveadown(agun)
if key=='l':
movebup(bgun)
if key=='k':
movebdown(bgun)
if key=='d':
shoota(agun)
if key=='j':
shootb(bgun)
#enviroment
ground = box(pos=(0,-8,0),size=(50,5,0),color=color.red)
wall = box(pos=(0,-8,0),size=(.25,20*random(),0),color=color.red)
#playerA
abody = box(pos=(-11,-5.25,0),size=(.5,.5,0),color=color.blue)
agun = cylinder(pos=(-11,-5.1,0),axis=(.8,.8,0),radius=(.08),color=color.blue)
#playerB
bbody= box(pos=(11,-5.25,0),size=(.5,.5,0),color=color.yellow)
bgun = cylinder(pos=(11,-5.1,0),axis=(-.8,.8,0),radius=(.08),color=color.yellow)
bulletlist = []
while True:
rate(1000)
checks(agun,bgun)
bulletlistupdate(bulletlist)
Any and all help is welcome!
Thanks much!
You can time things in python using the time module
import time
start = time.time()
finish = time.time()
print start # 1386269106.18
print finish # 1386269111.11
print (finish - start) # 4.9276599884
So when the player first starts pressing the button, save the time. Then save the time again when the player stops pressing the button. The difference between these two times is the number of seconds the player held the button.
[Edit] If all you can do is check if the key is pressed down, you can get the time inside the main loop and calculate dt (the amount of time that has passed):
t = time.time()
while True:
new_t = time.time()
dt = new_t - t
t = new_t
rate(1000)
checks(agun,bgun, dt)
bulletlistupdate(bulletlist)
Then pass dt to checks, and if the key is pressed down, you know the key has been held down for another dt seconds, and you can add it to your running total of time that it has been held down.
For the random you would need to enter a command similar to this:
random.randrange(5,31) #this would give you a random range between the numbers 4-30
I don't want to do your homework for you as I don't think you are asking for that. I hope this helps you.
I'm sorry this should be the correct code for you:
random.randint(7,40) # this would get you a random integer of 7-40
I apologize for the misinformation.