user4480584
user4480584

Reputation:

B-ship game follow up 2: AI and User IDK how to do alternating turns

From this

I have been making a b-ship game but I have run into a problem. It is 3x3, so it's a scaled down version of the actual game. We're using one ship for now.

I currently have the user hitting the AI section done, but how can i make it switch to the Ai's turn after one hit?

The AI, when it is his turn, knows that the user has part of a ship at [4] and that will stay that way for now. then He tries to hit [7], but if that doesn't work, try [1], or if that doesn't work, try [5]. And How can I do this for any edge??

import random

def drawboard(hitboard,hitboard2):
    print(' Opponent\'s          Your')
    print('    Ships            Ships')
    print('|   |   |   |    |   |   |   |')
    print('| ' + hitboard[7] + ' | ' + hitboard[8] + ' | ' + hitboard[9] + ' |    | ' + hitboard2[7] + ' | ' + hitboard2[8] + ' | ' + hitboard2[9] + ' |')
    print('|   |   |   |    |   |   |   |')
    print('-------------    -------------')
    print('|   |   |   |    |   |   |   |')
    print('| ' + hitboard[4] + ' | ' + hitboard[5] + ' | ' + hitboard[6] + ' |    | ' + hitboard2[4] + ' | ' + hitboard2[5] + ' | ' + hitboard2[6] + ' |')
    print('|   |   |   |    |   |   |   |')
    print('-------------    -------------')
    print('|   |   |   |    |   |   |   |')
    print('| ' + hitboard[1] + ' | ' + hitboard[2] + ' | ' + hitboard[3] + ' |    | ' + hitboard2[1] + ' | ' + hitboard2[2] + ' | ' + hitboard2[4] + ' |')
    print('|   |   |   |    |   |   |   |')
def aiships(hitboard,spot_hit,shipspots,hitboard2):
    if spot_hit in shipspots:
        hitboard[1] = 'x'
    else:
        hitboard[7] = 'o'
    drawboard(hitboard,hitboard2)

def playerships(hitboard,hitboard2, spot_hit, usershipspots):
    hitboard2[7] = 'x'
    print("\nComputer's turn.\n")
    spot_hit = random.choice(usershipspots)
    hitboard2[spot_hit] = 'x'
    if spot_hit not in usershipspots:
        hitboard2[spot_hit] = 'o'
    drawboard(hitboard,hitboard2)

def main():
    possiblespots = [[1,2],[2,3],[4,5],[5,6],[7,8],[8,9],[1,4],[4,7],[2,5],[5,8],[3,6],[6,9]]
    shipspots = random.choice(possiblespots)

    userspots = [[4,7],[4,1],[4,5]]
    usershipspots = random.choice(userspots)
    gameisplaying = True
    ai_spots = [4, 7, 1, 5]
    ai_index = 0
    while gameisplaying:
        hitboard = [' ' for i in range(10)]
        hitboard2 = [' ' for i in range(10)]
        hitboard2[usershipspots[0]] = 's'
        hitboard2[usershipspots[1]] = 's'
        userready = input('Place your ships. Type done when you finished placing it.')
        while not userready == 'done':
            userready = input('Type done when you locate your ship.  ')
        spot_hit = input('Where\'s the hit?: 1-9  ')
        while not (spot_hit in '1 2 3 4 5 6 7 8 9'.split()):
            spot_hit = input ('Please tell me where the hit is: 1-9  ')
        spot_hit = int(spot_hit)
        aiships(hitboard, spot_hit, shipspots, hitboard2)
        playerships(hitboard, hitboard2, ai_spots[ai_index], shipspots)
        ai_index += 1

main()

But wait, there's more! (billy mays reference)

No matter what number I put in, there will always be an O in the 7 space. Unless I put in the ship coordinates of the playerships (which is quite odd) which will create an X in the 1 space. Also there will always be an 's' in the 3 space on the 'your ships' board. (using numpad for numbers)

Upvotes: 0

Views: 85

Answers (1)

Alex Martelli
Alex Martelli

Reputation: 881853

So between the two current statements

aiships(hitboard,spot_hit,shipspots,hitboard2)
playerships(hitboard, hitboard2,spot_hit,shipspots)

you need to recompute spot_hit so it's 4 the first time, then 7, then 1, then 5 (we'll worry about "any hedge" in some other future Q, OK?-).

For the purpose, it's simplest to initialize, just before the while:

ai_spots = [4, 7, 1, 5]
ai_index = 0

and then transform those two statements into:

aiships(hitboard, spot_hit, shipspots, hitboard2)
playerships(hitboard, hitboard2, ai_spots[ai_index], shipspots)
ai_index += 1

I hope it's clear how it works here. BTW, a side note, the randomly different order of arguments in the two functions is confusing to no good purpose -- reorder things so that they're the same in both cases!

For the "all hedges" presumably you need a longer list for ai_spots and the ability to increment ai_index by more than one if an attempt was not successful -- which in turn requires playerships to give you a boolean return telling you if the attempt was successful or not, so you can use it to determine how much to change ai_index by.

However that's very premature as you still have many bigger bugs to think about right now. For example, consider the snippet:

spot_hit = random.choice(usershipspots)
if spot_hit in usershipspots:  

random.choice always returns one of the items in its argument -- so the check of whether its return value is indeed one of those items is completely redundant -- it will always be True and the body of the if clause will always execute.

No doubt you want to remove that recomputation of spot_hit as a random choice and accept the argument you're passed instead!

The if can remain of course and at the end of the function you can return spot_hit in usershipspots which is exactly the boolean telling you if the hit was successful or not.

Upvotes: 1

Related Questions