Reputation: 474
In this code of b-ship:
import random
import time
def drawboard(aiboard,playerboard):
print(' Opponent\'s Your')
print(' Ships Ships')
print('| | | | | | | |')
print('| ' + aiboard[7] + ' | ' + aiboard[8] + ' | ' + aiboard[9] + ' | | ' + playerboard[7] + ' | ' + playerboard[8] + ' | ' + playerboard[9] + ' |')
print('| | | | | | | |')
print('------------- -------------')
print('| | | | | | | |')
print('| ' + aiboard[4] + ' | ' + aiboard[5] + ' | ' + aiboard[6] + ' | | ' + playerboard[4] + ' | ' + playerboard[5] + ' | ' + playerboard[6] + ' |')
print('| | | | | | | |')
print('------------- -------------')
print('| | | | | | | |')
print('| ' + aiboard[1] + ' | ' + aiboard[2] + ' | ' + aiboard[3] + ' | | ' + playerboard[1] + ' | ' + playerboard[2] + ' | ' + playerboard[3] + ' |')
print('| | | | | | | |')
def playerhitai(aiboard,players_chosen_hit,aishipplaces,playerboard,usershipspots):
if players_chosen_hit in aishipplaces[0] or players_chosen_hit in aishipplaces[1]:
aiboard[players_chosen_hit] = 'x'
drawboard(aiboard,playerboard)
else:
aiboard[players_chosen_hit] = 'o'
drawboard(aiboard,playerboard)
def hitaroundhit(aiboard, playerboard,aishipplaces,players_chosen_hit,usershipspots):
spots = {1:[2,4],2:[1,3,5],3:[2,6],4:[1,5,7],5:[2,4,6,8],6:[3,5,9],7:[4,8],8:[5,7,9],9:[8,6]}
spot_dict = random.choice(spots[players_chosen_hit])
if playerboard[spot_dict] == 's':
pickX(aiboard,players_chosen_hit,aishipplaces,playerboard,usershipspots)
playerhitai(aiboard,players_chosen_hit,aishipplaces,playerboard,usershipspots)
else:
playerboard[spot_dict] = 'o'
playerhitai(aiboard,players_chosen_hit,aishipplaces,playerboard,usershipspots)
def pickX(aiboard,players_chosen_hit,aishipplaces,playerboard,usershipspots,aitakenmoves):
x = [1,2,3,4,5,6,7,8,9]
firsthitattempt = random.choice(x)
while x in aitakenmoves:
firsthitattempt = random.choice(x)
return firsthitattempt,aitakenmoves
def aihitplayer(aiboard,playerboard, usershipspots,players_chosen_hit,aishipplaces,aitakenmoves):
x,z = pickX(aiboard,players_chosen_hit,aishipplaces,playerboard,usershipspots,aitakenmoves)
if (aiboard[aishipplaces[0][0]] == 'x') and (aiboard[aishipplaces[0][1]] == 'x') and (aiboard[aishipplaces[1][0]] == 'x') and (aiboard[aishipplaces[1][1]] == 'x') and (aiboard[aishipplaces[1][2]] == 'x'):
return z
else:
time.sleep(1)
print("\nComputer's turn.\n")
time.sleep(1)
if x in usershipspots:
playerboard[x] = 'x'
drawboard(aiboard,playerboard)
else:
playerboard[x] = 'o'
drawboard(aiboard,playerboard)
return z
def getShipInfo(ship,possibleusershipplaces,usershipspots,playerboard):
while True:
try:
ship = int(input('Enter the 5 locations of your ship. Start with ship one (2 spaces) then do ship two (3 spaces).'))
if ship in possibleusershipplaces:
break
except ValueError:
time.sleep(0.5)
print("\nInvalid entry\n")
time.sleep(0.5)
while ship in usershipspots:
try:
ship = int(input('Spot already taken.'))
if ship not in possibleusershipplaces:
while True:
try:
ship = int(input('1-9 only!'))
except (ValueError, IndexError):
print('invalid input')
except (ValueError, IndexError):
time.sleep(0.5)
print("\nInvalid entry\n")
time.sleep(0.5)
playerboard[ship] = 's'
usershipspots.append(ship)
return playerboard,usershipspots
def ascii():
print(''' dMMMMb .aMMMb dMMMMMMP dMMMMMMP dMP dMMMMMP .dMMMb dMP dMP dMP dMMMMb''')
time.sleep(0.02)
print(''' dMP"dMP dMP"dMP dMP dMP dMP dMP dMP" VP dMP dMP amr dMP.dMP''')
time.sleep(0.02)
print(''' dMMMMK" dMMMMMP dMP dMP dMP dMMMP VMMMb dMMMMMP dMP dMMMMP" ''')
time.sleep(0.02)
print(''' dMP.aMF dMP dMP dMP dMP dMP dMP dP .dMP dMP dMP dMP dMP''')
time.sleep(0.02)
print('''dMMMMP" dMP dMP dMP dMP dMMMMMP dMMMMMP VMMMP" dMP dMP dMP dMP''')
time.sleep(1)
def playagain():
x = input("Play again? y/n")
if x == 'yes' or x == 'y' or x == 'Yes' or x == 'Y':
main()
else:
pass
def main():
print()
ascii()
print()
time.sleep(1)
print('''
############################################################################
# Instructions: #
# You have a 3x3 board. So does the AI. #
# Each person has 2 ships. One has a length of 2, other has a length of 3. #
# You can place the ships horizantally or vertically, not diagonally. #
# You must try to hit the AI ships. Each move you get one shot. #
# The player and AI alternates back and forth. #
# A hit is X and a miss is O. Your ships are designated with an S. #
# Whoever hits all of the other\'s ships first, wins the game. #
############################################################################
''')
time.sleep(5)
print()
aitakenmoves = []
twoships = [[1,2], [2,1], [1,4], [4,1], [2,3], [3,2], [2,5], [5,2], [3,6], [6,3], [4,5], [5,4], [4,7], [7,4], [5,6], [6,5], [5,8], [8,5], [6,9], [9,6], [7,8], [8,7], [8,9], [9,8]]
threeships = [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2], [1,4,7], [1,7,4], [4,1,7], [4,7,1], [7,4,1], [7,1,4], [2,5,8], [2,8,5], [5,8,2], [5,2,8], [8,5,2], [8,2,5], [3,6,9], [3,9,6], [6,9,3], [6,3,9], [9,6,3], [9,3,6], [4,5,6], [4,6,5], [5,6,4], [5,4,6], [6,5,4], [6,4,5], [7,8,9], [7,9,8], [9,8,7], [9,7,8], [8,7,9], [8,9,7]]
shipspots1 = random.choice(twoships)
shipspots2 = random.choice(threeships)
while (shipspots1[0] in shipspots2) or (shipspots1[1] in shipspots2):
shipspots1 = random.choice(twoships)
shipspots2 = random.choice(threeships)
aishipplaces = [shipspots1,shipspots2]
aiboard = [' ' for i in range(10)]
playerboard = [' ' for i in range(10)]
sh1sp1,sh1sp2,sh2sp1,sh2sp2,sh2sp3 = '','','','',''
possibleusershipplaces = [1,2,3,4,5,6,7,8,9]
players_inputted_hits = []
usershipspots = []
playerboard,usershipspots = getShipInfo(sh1sp1,possibleusershipplaces,usershipspots,playerboard)
playerboard,usershipspots = getShipInfo(sh1sp2,possibleusershipplaces,usershipspots,playerboard)
playerboard,usershipspots = getShipInfo(sh2sp1,possibleusershipplaces,usershipspots,playerboard)
playerboard,usershipspots = getShipInfo(sh2sp2,possibleusershipplaces,usershipspots,playerboard)
playerboard,usershipspots = getShipInfo(sh2sp3,possibleusershipplaces,usershipspots,playerboard)
players_inputted_hits = []
gameisplaying = True
while gameisplaying:
playersturn=True
while playersturn:
while True:
try:
players_chosen_hit = int(input('Where do you want to try to hit the AI?: 1-9 '))
if players_chosen_hit in possibleusershipplaces:
if players_chosen_hit in players_inputted_hits:
while True:
try:
players_chosen_hit = int(input('Already there! Try somewhere else!'))
if players_chosen_hit not in players_inputted_hits:
break
except ValueError:
time.sleep(0.5)
print("\nInvalid entry\n")
time.sleep(0.5)
break
except ValueError:
time.sleep(0.5)
print("\nInvalid entry\n")
time.sleep(0.5)
players_inputted_hits.append(players_chosen_hit)
playerhitai(aiboard, players_chosen_hit, aishipplaces, playerboard,usershipspots)
playersturn = False
aiturn = True
while aiturn:
aitakenmoves = aihitplayer(aiboard, playerboard, usershipspots,players_chosen_hit,aishipplaces,aitakenmoves)
aiturn = False
if (playerboard[usershipspots[0]] == 'x') and (playerboard[usershipspots[1]]) == 'x' and (playerboard[usershipspots[2]]) == 'x' and (playerboard[usershipspots[3]]) == 'x' and (playerboard[usershipspots[4]] == 'x'):
print("AI WINS!")
gameisplaying = False
elif (aiboard[aishipplaces[0][0]] == 'x') and (aiboard[aishipplaces[0][1]] == 'x') and (aiboard[aishipplaces[1][0]] == 'x') and (aiboard[aishipplaces[1][1]] == 'x') and (aiboard[aishipplaces[1][2]] == 'x'):
print("PLAYER WINS!")
gameisplaying = False
playagain()
main()
The AI is not always placing his move. It may be because his chosen move x = pickX()
is already in the aiboard
. I have made a list aitakenmoves
to try to alleviate this condition, but it still persists. Any assistance?
Upvotes: 0
Views: 74
Reputation: 155
The problem is occurring in the function pickX()
where you are trying to use the aitakenmoves
variables. There are two issues:
The line
aitakenmoves = []
deletes your record of moves taken each time you run the function, so the first move the AI picks is always chosen, no matter what moves it has taken before.
The aitakenmoves
variable is not stored in the global scope (which is probably why you decided to initialize it each time the function is called), so the variable disappears after the pickX()
function call ends. You will either want to keep track of the aitakenmoves
as either
main()
function that you pass to aihitplayer()
which in turn passes the variable to pickX()
. You can then pass the choice back to main()
from aihitplayer()
by using a multiple return as you have in other places in your code. OrB) a truly global variable, initialized before you call main()
that you then access in the pickX()
with the line
global aitakenmoves
that you can update directly in pickX()
.
I would personally recommend picking choice A, even though implementing choice B would definitely be easier to program since messing with global
can be very confusing.
P.S. At least with the code given here, when the player wins, the AI still gets to take its turn.
EDIT: An abbreviated demonstration of how to implement choice A properly.
def pickX(aitakenmoves):
firsthitattempt = random.randint(1, 9)
while firsthitattempt in aitakenmoves:
firsthitattempt = random.randint(1, 9)
return firsthitattempt
def aihitplayer(aiboard,playerboard, usershipspots,players_chosen_hit,aishipplaces, aitakenmoves):
x = pickX(aitakenmoves)
time.sleep(1)
print("\nComputer's turn.\n")
time.sleep(1)
if x in usershipspots:
playerboard[x] = 'x'
drawboard(aiboard,playerboard)
return True, x #AI makes a hit
else:
playerboard[x] = 'o'
drawboard(aiboard,playerboard)
return False, x #AI misses
def main():
# Initialization code
aitakenmoves = []
while gameisplaying:
# Game loop
ai_hit, location = aihitplayer(aiboard, playerboard, usershipspots,players_chosen_hit,aishipplaces,aitakenmoves)
aitakenmoves.append(location)
# Rest of game loop
Upvotes: 1