lab_cards/amazons/amazons_old.py

284 lines
10 KiB
Python

from random import *
from os import system, name
def clear():
if name == 'nt':
_ = system('cls')
else:
_ = system('clear')
class Square:
def __init__(self, location, name):
self.location = location #where the square is as an [x,y] pair
self.x = location[0]
self.y = location[1]
self.state = "empty" #behind the scenes data
self.display = " " #what the user will see
self.name = name #There's gotta be a better way!
#The names of the squares are according to chess convention,
#but the coordinates are according to usual matrix notation.
a1 = Square([0,3], "a1")
a2 = Square([0,2], "a2")
a3 = Square([0,1], "a3")
a4 = Square([0,0], "a4")
b1 = Square([1,3], "b1")
b2 = Square([1,2], "b2")
b3 = Square([1,1], "b3")
b4 = Square([1,0], "b4")
c1 = Square([2,3], "c1")
c2 = Square([2,2], "c2")
c3 = Square([2,1], "c3")
c4 = Square([2,0], "c4")
d1 = Square([3,3], "d1")
d2 = Square([3,2], "d2")
d3 = Square([3,1], "d3")
d4 = Square([3,0], "d4")
board=[a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4]
setup_seed = sample(board, 4) #We pick four squares for initial amazon placement
setup_seed[0].state = "ba1" #black amazon 1
setup_seed[1].state = "ba2" #black amazon 2
setup_seed[2].state = "wa1" #white amazon 1
setup_seed[3].state = "wa2" #white amazon 2
turn = "w" #White moves first.
turn_counter = 1
def display(): #This interprets the states of the squares for display
global turn, turn_counter, board
for box in board:
if box.state == "empty":
box.display = " "
if box.state == "ba1":
box.display = "B"
if box.state == "ba2":
box.display = "B"
if box.state == "wa1":
box.display = "W"
if box.state == "wa2":
box.display = "W"
if box.state == "fire":
box.display = "X"
def gui(): #This displays the board state to the user
global turn, turn_counter, board
clear()
display()
print(" a b c d")
print("4 "+a4.display+" "+b4.display+" "+c4.display+" "+d4.display)
print("3 "+a3.display+" "+b3.display+" "+c3.display+" "+d3.display)
print("2 "+a2.display+" "+b2.display+" "+c2.display+" "+d2.display)
print("1 "+a1.display+" "+b1.display+" "+c1.display+" "+d1.display)
if turn_counter%2 == 0:
print("It's black's turn.")
else:
print("It's white's turn.")
def choice_translate(box): #Takes the string inputs of the user and outputs corresponding square
global turn, turn_counter, board
if box == "a1":
return a1
if box == "a2":
return a2
if box == "a3":
return a3
if box == "a4":
return a4
if box == "b1":
return b1
if box == "b2":
return b2
if box == "b3":
return b3
if box == "b4":
return b4
if box == "c1":
return c1
if box == "c2":
return c2
if box == "c3":
return c3
if box == "c4":
return c4
if box == "d1":
return d1
if box == "d2":
return d2
if box == "d3":
return d3
if box == "d4":
return d4
else:
return False
def valid_move(start, end): #Checks to see if a mvoe is valid (for both amazons and arrows)
global turn, turn_counter, board
test_set=[] #This will be the set of squares between the start and end of the move.
#For reasons unknown, the test set always finds each eligible square twice. How to fix?
#There are three reasons to immediately reject a move:
if end.state != "empty": #If the ending square isn't empty
return False
if start == end: #If the ending square is the starting square
return False
#If the start and end aren't in the same row, column, or diagonal.
if (start.x != end.x) and (start.y != end.y) and (abs(start.x - end.x) != abs(start.y - end.y)):
return False
#If they are in the same column...
if start.x == end.x:
if start.y > end.y: #If we are going down....
for box in board: #...find the squares...
if box.x == start.x: #...in that column...
for i in range(1, abs(start.y-end.y)): #... between the start and end...
if box.y == start.y-i:
test_set.append(box) #... and add it to the list.
if start.y < end.y: #If we are going up... etc...
for box in board:
if box.x == start.x:
for i in range(1, abs(start.y-end.y)):
if box.y == start.y+i:
test_set.append(box)
#If they are in the same row...
if start.y == end.y:
if start.x > end.x: #going right....
for box in board:
if box.y == start.y:
for i in range(1, abs(start.x-end.x)):
if box.x == start.x-i:
test_set.append(box)
if start.x < end.x: #going left...
for box in board:
if box.y == start.y:
for i in range(1, abs(start.x-end.x)):
if box.x == start.x+i:
test_set.append(box)
#If they are on the same diagonal
if abs(start.x - end.x) == abs(start.y - end.y):
if (start.x < end.x) and (start.y < end.y): #going up and right
for box in board:
for i in range(1, abs(start.x-end.x)):
if ((box.x == start.x+i) and (box.y == start.y+i)):
test_set.append(box)
if (start.x > end.x) and (start.y > end.y): #going down and left
for box in board:
for i in range(1, abs(start.x-end.x)):
if ((box.x == start.x-i) and (box.y == start.y-i)):
test_set.append(box)
if (start.x > end.x) and (start.y < end.y): #going up and left
for box in board:
for i in range(1, abs(start.x-end.x)):
if ((box.x == start.x-i) and (box.y == start.y+i)):
test_set.append(box)
if (start.x < end.x) and (start.y > end.y): #going down and right
for box in board:
for i in range(1, abs(start.x-end.x)):
if ((box.x == start.x+i) and (box.y == start.y-i)):
test_set.append(box)
for test in test_set: #now make sure all of the squares we've selected are indeed empty
if test.state != "empty":
return False
return True
def possible_moves(amazon): #outputs a list of squares that can be reached by an amazon
moves=[]
for box in board:
if valid_move(amazon, box):
moves.append(box)
return(moves)
def play():
global turn, turn_counter, board
gui()
#We check which amazons can legally move
movable_amazons=[]
for box in board:
if box.state == turn+"a1":
if len(possible_moves(box)) != 0:
movable_amazons.append(box.name)
if box.state == turn+"a2":
if len(possible_moves(box)) != 0:
movable_amazons.append(box.name)
#If none can move, then the game is over!
if len(movable_amazons)==0:
if turn_counter%2 == 0:
input("White wins!")
exit(0)
if turn_counter%2 == 1:
input("Black wins!")
exit(0)
#Otherwise, the player chooses an amazon to move
if len(movable_amazons) == 2: #If both can move they have a choice
amazon_choice = input("Choose a square containing one of your amazons, either "+movable_amazons[0]+" or "+movable_amazons[1]+": ")
while amazon_choice not in movable_amazons:
amazon_choice = input("That's not one of the options. Try again: ")
if len(movable_amazons) == 1: #If only one can move, they have no choice
amazon_choice = movable_amazons[0]
gui()
#The player chooses a square to move to
print("You must move the amazon on "+amazon_choice+". Choose the square you want to move to.")
print("Which of the following would you like to move to?")
amazon_choice = choice_translate(amazon_choice)
choices = [] #We have a list to display to the user...
for option in possible_moves(amazon_choice): #...consisting of their possible moves.
choices.append(option.name)
move_choice = choice_translate(input(choices))
#The following three while statements only catch exemptions if made in this order.
#So if the user first inputs a square correctly, but it's not a possible move,
#and then they enter in gibberish, it wigs out. How to fix?
while move_choice == False: #choice_translate outputs False when the input isn't a square name
move_choice = choice_translate(input("That's not a valid move. Try again: "))
while move_choice.name not in choices:
move_choice = choice_translate(input("That's not an option. Try again: "))
while valid_move(amazon_choice, move_choice) == False:
move_choice = choice_translate(input("That amazon can't move there. Try again: "))
#If all goes well, we make the move by changing the states of the squares.
if valid_move(amazon_choice, move_choice):
move_choice.state = amazon_choice.state
amazon_choice.state = "empty"
gui()
#The player chooses a square to shoot
choices = []
for option in possible_moves(move_choice):
choices.append(option.name)
print("Choose the square you want to set aflame: ")
burn_choice = choice_translate(input(choices))
#These three statements have the same problem as those above.
while burn_choice == False:
burn_choice = choice_translate(input("That's not the name of any square. Try again: "))
while burn_choice.state != "empty":
burn_choice = choice_translate(input("That's square isn't empty. Try again: "))
while valid_move(move_choice, burn_choice) == False:
burn_choice = choice_translate(input("You can't shoot there. Try again: "))
burn_choice.state = "fire"
#Bookkeepping for turn taking
turn_counter+=1
if turn_counter%2 == 0:
turn = "b"
if turn_counter%2 == 1:
turn = "w"
while True:
play()
#Next Steps:
#have students change the abilities of the amazons, size of the board, etc.
#Add a class to record game state!?!?!?