code
from pygame import freetype
import pygame
from random import randint
print("Instructions: Pick a number of players three through nine, one of them is a Sellsword, another a member of the Town called the Pigeon, and another a member of the Town called the katze, the rest being Vanilla Townies. At daytime, the living players communicate with each other and may use the voting system by typing their number and then typing the number of the person they would like to vote. If they used the voting system by mistake, they may press 'c'. If they want to remove their current vote, they may re-vote the person they are currently voting. If they would like to vote for no execution, they may press 0. The day goes on until someone is voted by the majority and executed.")
print("If the person who was executed was a Sellsword, the Town win. If they were a member of the Town, their exact name is revealed and night begins. At night, the Sellsword chooses who they wish to kill, using 0 if they wish to kill nobody. After that, the Pigeon, if they are alive, may check if their target is the Sellsword or is the katze (they won't know which). Then once that happens, the exact name of the person who died is revealed and day begins again. This cycle continues until the Sellsword is executed or until there is only one member of the Town, in which case the Sellsword wins.")
print("Note: If the screen gets crowded from all the voting, press 'b' to refresh it to how it was at the start of the day.")
while True:
players = int(input("How many players are playing? "))
if players > 9 or players < 3:
print("That is an invalid number of players!")
else:
break
#Change the 1920 if the screen you are using is not 1920 pixels wide.
#Change the 1080 if the screen you are using is not 1080 pixels tall.
SCREEN_WIDTH = int(1920*players)
SCREEN_HEIGHT = 1080
#Change the following if you want the background, text color, and font size to be different
BACKGROUND = (255, 255, 255)
TEXT_COLOR = (0, 0, 0)
FONT_SIZE = SCREEN_HEIGHT/10
KATZE = 0
#Do NOT change ANYTHING past this line unless you REALLY know what you're doing and how to decipher Pigeon's terrible code.
while True:
MAFIA = randint(1, players)
PIGEON = randint(1, players)
if players >= 7:
KATZE = randint(1, players)
if MAFIA == PIGEON or KATZE == PIGEON or KATZE == MAFIA:
pass
else:
break
pygame.init()
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption("Mafia!")
on = True
screen.fill(BACKGROUND)
FONT = freetype.SysFont("arial", FONT_SIZE)
typed = False
ready = False
day = 0
line = 0
playerVotes = []
noExe = 0
announcements = []
nightAnnouncements = []
firstUnconfirm = True
aliveMafia = 1
aliveTown = players-aliveMafia
voteperson = "skip"
skip = False
unconfirm = False
PigeonOver = False
NotEnd = True
for x in range(players):
playerVotes.append(x+1)
playerVotes.append(0)
playerVotes.append(0)
def allScreens(word):
for x in range(players):
FONT.render_to(screen, (int(SCREEN_WIDTH/players*x), int(line*FONT_SIZE)), word, TEXT_COLOR)
pygame.display.update()
def Type(word, player):
FONT.render_to(screen, (int(SCREEN_WIDTH/players*player), int(line*FONT_SIZE)), word, TEXT_COLOR)
pygame.display.update()
def blank(existing=False, time="day", turn=0):
global line
screen.fill(BACKGROUND)
for x in range(players):
if playerVotes[x*3] == 0:
line = 0
Type("You are dead and are unable to vote! It is "+time+" "+str(int(day))+"!", x)
elif x+1 == MAFIA:
line = 0
Type("You are the Sellsword! It is "+time+" "+str(int(day))+"!", x)
elif x+1 == PIGEON:
line = 0
Type("You are the Pigeon! It is "+time+" "+str(int(day))+"!", x)
elif x+1 == KATZE:
line = 0
Type("You are the katze! It is "+time+" "+str(int(day))+"!", x)
else:
line = 0
Type("You are a Vanilla Townie! It is "+time+" "+str(int(day))+"!", x)
line = 1
for x in range(players):
Type("You are Player "+str(x+1)+"!", x)
if existing:
for x in announcements:
line += 1
allScreens(x)
while on:
one = False
two = False
three = False
four = False
five = False
six = False
seven = False
eight = False
nine = False
zero = False
cancel = False
blankScreen = False
dayType = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
on = False
if event.type == pygame.KEYUP:
typed = False
if not typed:
if event.type == pygame.KEYDOWN:
typed = True
if event.key == pygame.K_r:
ready = True
if event.key == pygame.K_c:
cancel = True
if event.key == pygame.K_1:
one = True
if event.key == pygame.K_2:
two = True
if event.key == pygame.K_3:
three = True
if event.key == pygame.K_4:
four = True
if event.key == pygame.K_5:
five = True
if event.key == pygame.K_6:
six = True
if event.key == pygame. K_7:
seven = True
if event.key == pygame.K_8:
eight = True
if event.key == pygame.K_9:
nine = True
if event.key == pygame.K_0:
zero = True
if event.key == pygame.K_d:
dayType = True
if event.key == pygame.K_b:
blankScreen = True
if blankScreen:
if int(day) == day:
announcements = []
blank()
inputs = [one, two, three, four, five, six, seven, eight, nine]
if aliveTown == aliveMafia:
if NotEnd:
screen.fill(BACKGROUND)
NotEnd = False
line = 0
allScreens("The Sellsword (Player "+str(MAFIA)+") wins!")
line += 1
allScreens("Player "+str(PIGEON)+" loses as the Pigeon.")
if KATZE > 0:
line += 1
allScreens("Player "+str(KATZE)+" loses as the katze.")
line += 1
allScreens("Chloe wins as the Chloe!")
line += 1
allScreens("Everyone else loses as Vanilla Townies.")
elif aliveMafia == 0:
if NotEnd:
screen.fill(BACKGROUND)
NotEnd = False
line = 0
allScreens("The Town win! Player "+str(PIGEON)+" wins as the Pigeon!")
if KATZE > 0:
line += 1
allScreens("Player "+str(KATZE)+" wins as the katze!")
line += 1
allScreens("Chloe wins as the Chloe!")
line += 1
allScreens("Player "+str(MAFIA)+" loses as the Sellsword.")
line += 1
allScreens("Everyone else wins as Vanilla Townies!")
elif not ready:
allScreens('Press "r" when you are ready!')
elif day == 0:
day = 1
blank()
elif day-int(day) == 0:
if voteperson != "skip":
if playerVotes[voteperson*3] == 0:
line -= 1
voteperson = "skip"
continue
for x in range(players):
if x == voteperson:
Type("Type the number of who you want to vote", voteperson)
else:
Type("The voting system is in use! Please do not type!", x)
if zero:
if playerVotes[voteperson*3+1] == 0:
noExe += 1
playerVotes[voteperson*3+1] = "noExe"
Vote = "voted for"
elif playerVotes[voteperson*3+1] == "noExe":
noExe -= 1
playerVotes[voteperson*3+1] = 0
Vote = "unvoted"
else:
noExe += 1
playerVotes[playerVotes[voteperson*3+1]*3-1] -= 1
playerVotes[voteperson*3+1] = "noExe"
Vote = "changed their vote to"
announcements.append("Player "+str(voteperson+1)+" has "+Vote+" no execution")
blank(True)
voteperson = "skip"
continue
tick = 0
for x in range(len(inputs)):
if x >= players:
break
if inputs[x]:
if playerVotes[voteperson*3+1] == "noExe":
playerVotes[x*3+2] += 1
noExe -= 1
playerVotes[voteperson*3+1] = x+1
Vote = "changed their vote to"
elif playerVotes[voteperson*3+1] == 0:
playerVotes[x*3+2] += 1
playerVotes[voteperson*3+1] = x+1
Vote = "voted"
elif playerVotes[voteperson*3+1] == x+1:
playerVotes[x*3+2] -= 1
playerVotes[voteperson*3+1] = 0
Vote = "unvoted"
else:
playerVotes[x*3+2] += 1
playerVotes[playerVotes[voteperson*3+1]*3-1] -= 1
playerVotes[voteperson*3+1] = x+1
Vote = "changed their vote to"
announcements.append("Player "+str(voteperson+1)+" has "+Vote+" Player "+str(x+1))
blank(True)
voteperson = "skip"
break
tick += 1
if cancel:
voteperson = "skip"
blank(True)
continue
number = 0
for x in range(len(inputs)):
if inputs[x] and x < players:
line += 1
voteperson = x
break
for x in range(2, len(playerVotes), 3):
if noExe >= int((aliveMafia+aliveTown)/2)+1:
blank()
screen.fill(BACKGROUND)
line = 0
announcements = []
announcements.append("No one has been executed!")
day += 0.5
noExe = 0
for x in range(len(playerVotes)):
if x/3 != int(x/3):
playerVotes[x] = 0
blank(True, "night")
line = 3
for x in range(players):
if x+1 == MAFIA:
Type("Type who you want to kill!", x)
elif x+1 == PIGEON:
Type("Please wait while the Sellsword submits their kill!", x)
else:
Type("Please wait while all actions are submitted!", x)
break
if playerVotes[x] >= int((aliveMafia+aliveTown)/2)+1:
blank()
screen.fill(BACKGROUND)
line = 0
announcements = []
if playerVotes[x-2] == MAFIA:
aliveMafia -= 1
line = 0
announcements.append("Player "+str(playerVotes[x-2])+" was the Sellsword!")
elif playerVotes[x-2] == PIGEON:
aliveTown -= 1
line = 0
announcements.append("Player "+str(playerVotes[x-2])+" was the Pigeon!")
elif playerVotes[x-2] == KATZE:
aliveTown -= 1
line = 0
announcements.append("Player "+str(playerVotes[x-2])+" was the katze!")
else:
aliveTown -= 1
line = 0
announcements.append("Player "+str(playerVotes[x-2])+" was a Vanilla Townie!")
playerVotes[x-2] = 0
day += 0.5
noExe = 0
for x in range(len(playerVotes)):
if x/3 != int(x/3):
playerVotes[x] = 0
blank(True, "night")
line = 3
for x in range(players):
if x+1 == MAFIA:
Type("Type who you want to kill!", x)
elif x+1 == PIGEON:
Type("Please wait while the Sellsword submits their kill!", x)
else:
Type("Please wait while all actions are submitted!", x)
break
elif unconfirm:
if firstUnconfirm:
screen.fill(BACKGROUND)
line = 0
if kill != "nobody":
playerVotes[kill*3] = 0
allScreens(nightAnnouncement)
line = 1
allScreens("Press 'd' once you have acknowledged this info!")
firstUnconfirm = False
if dayType:
day += 0.25
announcements = []
blank()
firstUnconfirm = True
unconfirm = False
elif day-int(day) == 0.5:
for x in range(len(inputs)):
if zero:
blank(True, "night")
line = 3
nightAnnouncement = "Nobody has died!"
kill = "nobody"
day += 0.25
unconfirm = True
for x in range(players):
if x+1 == PIGEON and playerVotes[(PIGEON-1)*3] > 0:
Type("Type who you want to investigate!", x)
elif x+1 == MAFIA:
Type("Please wait for the Pigeon to investigate someone!", x)
else:
Type("Please wait while all actions are submitted!", x)
break
if inputs[x]:
if x+1 == MAFIA:
line += 1
Type("You cannot stab yourself!", MAFIA-1)
break
elif playerVotes[x*3] == 0:
line += 1
Type("You cannot kill someone who has already been killed!", MAFIA-1)
break
elif x+1 == KATZE:
kill = x
nightAnnouncement = "Player "+str(x+1)+" has died! They were the katze!"
elif x+1 == PIGEON:
kill = "nobody"
playerVotes[x*3] = 0
nightAnnouncement = "Player "+str(x+1)+" has died! They were the Pigeon!"
else:
kill = x
nightAnnouncement = "Player "+str(x+1)+" has died! They were a Vanilla Townie!"
aliveTown -= 1
day += 0.25
blank(True, "night")
line = 3
for x in range(players):
if x+1 == PIGEON and playerVotes[(PIGEON-1)*3] > 0:
Type("Type who you want to investigate!", x)
elif x+1 == MAFIA:
Type("Please wait for the Pigeon to investigate someone!", x)
else:
Type("Please wait while all actions are submitted!", x)
break
elif playerVotes[(PIGEON-1)*3] > 0:
for x in range(len(inputs)):
if inputs[x]:
if playerVotes[x*3] == 0 or x+1 == PIGEON:
line += 1
Type("You already know what Player "+str(x+1)+" is!", PIGEON-1)
break
elif x+1 == KATZE or x+1 == MAFIA:
line += 1
if KATZE > 0:
Type("Player "+str(x+1)+" is the Sellsword or the katze!", PIGEON-1)
else:
Type("Player "+str(x+1)+" is the Sellsword!", PIGEON-1)
else:
line += 1
Type("Player "+str(x+1)+" is a Vanilla Townie!", PIGEON-1)
line += 1
Type("Press 'd' once you have acknowledged this info!", PIGEON-1)
PigeonOver = True
if dayType and PigeonOver:
unconfirm = True
PigeonOver = False
else:
unconfirm = True
pygame.quit()