Instructions
Requirements and Specifications
Source Code
"""
File: FILENAME.py
Author: YOUR NAME
Date: THE DATE
Section: YOUR DISCUSSION SECTION NUMBER
E-mail: YOUR_EMAIL@umbc.edu
Description:
Play mancala
"""
BLOCK_WIDTH = 6
BLOCK_HEIGHT = 5
BLOCK_SEP = "*"
SPACE = ' '
LEFT_JUSTIFY = "{:<" + str(BLOCK_WIDTH) + "}"
RIGHT_JUSTIFY = "{:>" + str(BLOCK_WIDTH) + "}"
MANCALA_NAME = 3 # Position of the name in the mancala
MANCALA_STONES = 8 # Position of the stones in the mancala
CUP_STONES = 3 # Position of the stones in the cup
def draw_board(top_cups, bottom_cups, mancala_a, mancala_b):
"""
draw_board is the function that you should call in order to draw the board.
top_cups and bottom_cups are 2d lists of strings. Each string should be
length BLOCK_WIDTH and each list should be of length BLOCK_HEIGHT.
mancala_a and mancala_b should be 2d lists of strings. Each string should be
BLOCK_WIDTH in length, and each list should be 2 * BLOCK_HEIGHT + 1
:param top_cups: This should be a list of strings that represents cups 1 to 6
(Each list should be at least BLOCK_HEIGHT in length, since each string in the list is
a line.)
:param bottom_cups: This should be a list of strings that represents cups 8 to 13
(Each list should be at least BLOCK_HEIGHT in length, since each string in the list is
a line.)
:param mancala_a: This should be a list of 2 * BLOCK_HEIGHT + 1 in length which
represents the mancala at position 7.
:param mancala_b: This should be a list of 2 * BLOCK_HEIGHT + 1 in length which
represents the mancala at position 0.
"""
board = [[SPACE for _ in range((BLOCK_WIDTH + 1) * (len(top_cups) + 2) + 1)] for _
in range(BLOCK_HEIGHT * 2 + 3)]
for p in range(len(board)):
board[p][0] = BLOCK_SEP
board[p][len(board[0]) - 1] = BLOCK_SEP
for q in range(len(board[0])):
board[0][q] = BLOCK_SEP
board[len(board) - 1][q] = BLOCK_SEP
# draw midline
for p in range(BLOCK_WIDTH + 1, (BLOCK_WIDTH + 1) * (len(top_cups) + 1) + 1):
board[BLOCK_HEIGHT + 1][p] = BLOCK_SEP
for i in range(len(top_cups)):
for p in range(len(board)):
board[p][(1 + i) * (1 + BLOCK_WIDTH)] = BLOCK_SEP
for p in range(len(board)):
board[p][1 + BLOCK_WIDTH] = BLOCK_SEP
board[p][len(board[0]) - BLOCK_WIDTH - 2] = BLOCK_SEP
for i in range(len(top_cups)):
draw_block(board, i, 0, top_cups[i])
draw_block(board, i, 1, bottom_cups[i])
draw_mancala(0, mancala_a, board)
draw_mancala(1, mancala_b, board)
print('\n'.join([''.join(board[i]) for i in range(len(board))]))
def draw_mancala(fore_or_aft, mancala_data, the_board):
"""
Draw_mancala is a helper function for the draw_board function.
:param fore_or_aft: front or back (0, or 1)
:param mancala_data: a list of strings of length 2 * BLOCK_HEIGHT + 1 each string
of length BLOCK_WIDTH
:param the_board: a 2d-list of characters which we are creating to print the
board.
"""
if fore_or_aft == 0:
for i in range(len(mancala_data)):
data = mancala_data[i][0: BLOCK_WIDTH].rjust(BLOCK_WIDTH)
for j in range(len(mancala_data[0])):
the_board[1 + i][1 + j] = data[j]
else:
for i in range(len(mancala_data)):
data = mancala_data[i][0: BLOCK_WIDTH].rjust(BLOCK_WIDTH)
for j in range(len(mancala_data[0])):
the_board[1 + i][len(the_board[0]) - BLOCK_WIDTH - 1 + j] = data[j]
def draw_block(the_board, pos_x, pos_y, block_data):
"""
Draw block is a helper function for the draw_board function.
:param the_board: the board is the 2d grid of characters we're filling in
:param pos_x: which cup it is
:param pos_y: upper or lower
:param block_data: the list of strings to put into the block.
"""
for i in range(BLOCK_HEIGHT):
data = block_data[i][0:BLOCK_WIDTH].rjust(BLOCK_WIDTH)
for j in range(BLOCK_WIDTH):
the_board[1 + pos_y * (BLOCK_HEIGHT + 1) + i][1 + (pos_x + 1) * (BLOCK_WIDTH + 1) + j] = data[j]
def get_player():
"""
Get the player names
:return: Tuple consisting of player 1 and player 2 name
"""
player1_name = input("Player 1 please tell me your name: ")
player2_name = input("Player 2 please tell me your name: ");
return player1_name, player2_name
def is_all_cleared(cups):
"""
Check if cups are all cleared
:param cups: List of cups
:return: True if cleared
"""
for cup in cups:
if int(cup[CUP_STONES].strip()) > 0:
return False
return True
def take_turn(player, top_cups, bottom_cups, mancala_a, mancala_b):
"""
Print the board, ask for the new move, verify if that is a legal move, and then make it.
:param player: Current player making the turn, either 1 or 2
:param top_cups: Current state of the cups at the top
:param bottom_cups: Current state of the cups at the bottom
:param mancala_a: State of the first mancala
:param mancala_b: State of the second mancala
:return False if game over, otherwise true
"""
while not is_all_cleared(top_cups) and not is_all_cleared(bottom_cups):
draw_board(top_cups, bottom_cups, mancala_a, mancala_b)
# Ask current player to make a move
if player == 1:
player_name = mancala_a[MANCALA_NAME]
else:
player_name = mancala_b[MANCALA_NAME]
cup_number = int(input(player_name.strip() + " What cup do you want to move? "))
# Calculate the indexing of array based on cup number
if 1 <= cup_number <= 6:
cup_number -= 1
num_stones = int(top_cups[cup_number][CUP_STONES].strip())
top_cups[cup_number][CUP_STONES] = RIGHT_JUSTIFY.format("0")
current_row = "TOP"
elif 8 <= cup_number <= 13:
cup_number = 5 - (cup_number - 8)
num_stones = int(bottom_cups[cup_number][CUP_STONES].strip())
bottom_cups[cup_number][CUP_STONES] = RIGHT_JUSTIFY.format("0")
current_row = "BOTTOM"
else:
print("You should be touching cup number 1 to 6 or 8 to 13 only")
continue
if num_stones == 0:
print("You chose a cup with no stone. Try again.")
break
# Distribute the stones clock-wise
while num_stones > 0:
if current_row == "TOP":
# When on top go left to right
cup_number += 1
if cup_number == 6:
stones = int(mancala_b[MANCALA_STONES].strip()) + 1
num_stones -= 1
mancala_b[MANCALA_STONES] = LEFT_JUSTIFY.format(str(stones))
# Ended in a mancala
break
# Switch to bottom
current_row = "BOTTOM"
cup_number = 6
else:
stones = int(top_cups[cup_number][CUP_STONES].strip()) + 1
num_stones -= 1
top_cups[cup_number][CUP_STONES] = RIGHT_JUSTIFY.format(str(stones))
elif current_row == "BOTTOM":
# When at bottom go right to left
cup_number -= 1
if cup_number == -1:
stones = int(mancala_a[MANCALA_STONES].strip()) + 1
num_stones -= 1
mancala_a[MANCALA_STONES] = LEFT_JUSTIFY.format(str(stones))
if num_stones == 0:
# Ended in a mancala
break
# Switch to top
current_row = "TOP"
cup_number = -1
else:
stones = int(bottom_cups[cup_number][CUP_STONES].strip()) + 1
num_stones -= 1
bottom_cups[cup_number][CUP_STONES] = RIGHT_JUSTIFY.format(str(stones))
# If the player stopped on a mancala, they get a turn again
if cup_number == -1 or cup_number == 6:
print("Your last stone landed in a mancala.")
print("Go again please...")
else:
return True
draw_board(top_cups, bottom_cups, mancala_a, mancala_b)
return False
def initialize_cups(cup_numbers):
"""
Create create the list of cups
:return: List of cups
"""
initial_stones = 4
cups = []
for cup_number in cup_numbers:
cup = [LEFT_JUSTIFY.format("Cup"),
RIGHT_JUSTIFY.format(str(cup_number)),
LEFT_JUSTIFY.format("Stones"),
RIGHT_JUSTIFY.format(str(initial_stones)),
LEFT_JUSTIFY.format("")]
cups.append(cup)
return cups
def initialize_mancala(player_name):
"""
Create a mancala
:param player_name: Name of player to be placed on the mancala
:return: Mancala
"""
left_justify = "{:<" + str(BLOCK_WIDTH) + "}"
mancala = [LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format(player_name)[:BLOCK_WIDTH],
LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format("Stones"),
LEFT_JUSTIFY.format("0"),
LEFT_JUSTIFY.format(""),
LEFT_JUSTIFY.format("")]
return mancala
def run_game():
"""
Setup the board, alternate between players, and determine the winner
at the end.
:return: None
"""
# Initialize the top cops and bottom cups
top_cups = initialize_cups([1, 2, 3, 4, 5, 6])
bottom_cups = initialize_cups([13, 12, 11, 10, 9, 8])
# Initialize the mancalas
player1_name, player2_name = get_player();
mancala_a = initialize_mancala(player2_name)
mancala_b = initialize_mancala(player1_name)
player = 2
while take_turn(player, top_cups, bottom_cups, mancala_a, mancala_b):
# Each player takes turn and stops if game is over
if player == 1:
player = 2
else:
player = 1
# Evaluate the winner
if int(mancala_a[MANCALA_STONES].strip()) > int(mancala_b[MANCALA_STONES].strip()):
print(mancala_a[MANCALA_NAME].strip() + " is the winner")
elif int(mancala_a[MANCALA_STONES].strip()) < int(mancala_b[MANCALA_STONES].strip()):
print(mancala_b[MANCALA_NAME].strip() + " is the winner")
else:
print("It's a tie")
if __name__ == "__main__":
run_game()