Python Multiplayer noughts and crosses [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
So I made a single player noughts and crosses in Python a little while ago in school.
score=[[' ',' ',' '],[' ',' ',' '],[' ',' ',' ']]
global attempts
attempts = 0
from random import randint
from time import sleep
def grid(): #draws playing grid
hideturtle()
speed(0)
pensize(0)
penup()
setpos(-200, -67)
pendown()
fd(400)
penup()
setpos(-200, 66)
pendown()
fd(400)
penup()
seth(90)
setpos(-67, -200)
pendown()
fd(400)
penup()
setpos(66, -200)
pendown()
fd(400)
def drawShape(s, x, y): #draws shape in grid box x and y = coord, s = shape type
hideturtle()
speed(100)
pensize(6)
penup()
if s == 'X': #draws 'X'
pencolor("orange")
setpos(-266+(133*x), -266+(133*y))
pendown()
seth(135)
fd(50)
rt(180)
fd(100)
rt(180)
fd(50)
rt(90)
fd(50)
rt(180)
fd(100)
elif s == 'O': #draws 'O'
pencolor("green")
setpos(-266+(133*x), -266+(133*y)-40)
seth(0)
pendown()
circle(40)
def ai(): #EXPERIMENTAL AI
x=0
y=0
d='O'
e='O'
f='O'
for i in range(3): #checks positions
if i == 0:
d=' '
elif i == 1:
d='O'
e=' '
elif i == 2:
d='O'
e='O'
f=' '
for c in range(3):
if score[c][0] == d and score[c][1] == e and score[c][2] == f:
x = c+1
y = i+1
print('v',c)
elif score[c][0] == d and score[c][1] == e and score[c][2] == f:
x = i=1
y = c+1
print('h',c)
if score[0][0] == d and score[1][1] == e and score[2][2] == f:
print('lr',i)
x = i+1
y = i+1
elif score[0][2] == d and score[1][1] == e and score[2][0] == f:
print('rl',i)
x = i+1
y = 4-i
d='X'
e='X'
f='X'
if x == 0 and y == 0: #checks oposition positions
for i in range(3):
if i == 0:
d=' '
elif i == 1:
d='X'
e=' '
elif i == 2:
d='X'
e='X'
f=' '
for c in range(3):
if score[c][0] == d and score[c][1] == e and score[c][2] == f:
x = c+1
y = i+1
print('op v')
elif score[c][0] == d and score[c][1] == e and score[c][2] == f:
x = i=1
y = c+1
print('op v')
if score[0][0] == d and score[1][1] == e and score[2][2] == f:
x = i+1
y = i+1
print('op bt')
elif score[0][2] == d and score[1][1] == e and score[2][0] == f:
x = i+1
y = 4-i
print('op tb')
if x == 0 and y == 0: #if no playable positions uses random
x = randint(1,3)
y = randint(1,3)
return x, y
def valid(u,x,y): #checks player move is valid
global attempts
if x > 3 or y > 3:
print ('Coordinate must be between 1 & 3')
elif x == '' or y == '':
print("Enter something!")
elif score[y-1][x-1] == ' ':
score[y-1][x-1] = u
drawShape(u, x, y)
attempts +=1
return True
elif score[y-1][x-1] == u:
print("You've already gone here! ")
return False
elif score[y-1][x-1] != u:
print("The other player is here! ")
return False
def userAgent(u): #makes AI or user prompts and sets array
global attempts
global a
global b
if u == 0:
a, b = ai()
score[b-1][a-1] = 'O'
print("The computer is taking its turn...")
print(a,b)
sleep(1)
drawShape('O', a, b)
attempts +=1
else:
x = input("Player "+u+": enter x coordinate (1-3) ")
y = input("Player "+u+": enter y coordinate (1-3) ")
try:
x = int(x)
y = int(y)
except ValueError:
print("That's not a valid number!")
userAgent(u)
while True:
if valid(u,x,y) == True:
break
x = input("Player "+u+": enter x coordinate (1-3) ")
y = input("Player "+u+": enter y coordinate (1-3) ")
try:
x = int(x)
y = int(y)
except ValueError:
print("That's not a valid number!")
def checkWin(n): #checks for a player win (3 in row) or stalemate
for i in range(3):
if score[i][0] == n and score[i][1] == n and score[i][2] == n:
print("Player "+n+" won!")
return True
elif score[0][i] == n and score[1][i] == n and score[2][i] == n:
print("Player "+n+" won!")
return True
if score[0][0] == n and score[1][1] == n and score[2][2] == n:
print("Player "+n+" won!")
return True
elif score[0][2] == n and score[1][1] == n and score[2][0] == n:
print("Player "+n+" won!")
return True
elif attempts == 9:
print("Stalemate!")
return True
else:
return False
def printGrid():
print(score[2])
print(score[1])
print(score[0])
from turtle import *
grid()
p = input("Are you playing by yourself? (SINGLE PLAYER EXPERIMENTAL) (y/n) ")
while True: #runs game until player win
if p == 'y':
userAgent('X')
printGrid()
if checkWin('X') == True:
break
userAgent(0)
printGrid()
if checkWin('O') == True:
break
elif p == 'n':
userAgent('X')
if checkWin('X') == True:
break
userAgent('O')
if checkWin('O') == True:
break
else:
print("You need to type y or n - try again!")
p = input("Are you playing by yourself? (SINGLE PLAYER EXPERIMENTAL) (y/n) ")
input('Press ENTER to exit')
Just ignore that AI function it's now permanently experimental (doesn't work) but that's not the problem.
I'm helping out at my school's open evening and I thought it'd be cool if 2 people could play against each other on different computers. So I'd host the server on my home PC with port forwarding, doing all the logic, and the clients would just take inputs, send them onto the server and draw moves by both players. I know HTTP POST/GET, but how would I get the server to tell the client the other player moved? I've looked into Twisted and it seems good, but I really don't understand classes (I've only been programming for a little while).
This would be on a school computer so I have no access to port forwarding for the client. Ideally I'd also have an IP whitelist so only the computer's I want can access the server....
Soooo can anyone help me out here? I just need to understand what code I'd need for the server and how the client would interact with it. Thanks :)

You can start from the twisted chatserver example
"""The most basic chat protocol possible.
run me with twistd -y chatserver.py, and then connect with multiple
telnet clients to port 1025
"""
from twisted.protocols import basic
class MyChat(basic.LineReceiver):
def connectionMade(self):
print "Got new client!"
self.factory.clients.append(self)
def connectionLost(self, reason):
print "Lost a client!"
self.factory.clients.remove(self)
def lineReceived(self, line):
print "received", repr(line)
for c in self.factory.clients:
c.message(line)
def message(self, message):
self.transport.write(message + '\n')
from twisted.internet import protocol
from twisted.application import service, internet
factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []
application = service.Application("chatserver")
internet.TCPServer(1025, factory).setServiceParent(application)
The clients can use Python's builtin telnetlib to connect
Later on you can upgrade to using twisted for the client connections if you like.

The easiest way to have both clients interact through a server is to have both clients poll the server for updates. (you can do server side events, but that is way too complicated for what you are looking for).
However, if they are within the same network I recommend opening a socket server and client on each device directly communicating.
The way I would do it is to this:
Sockets servers are opened on both machines
Whoever starts the game opens a socket client and sends a the move directly to server, then reopens a socket server
The next move the computer opens a client and sends a move back to server.
This takes out all the unnecessary code for running a server.
See the python manual for sockets. There are great examples at the bottom for both server/client side.
https://docs.python.org/2/library/socket.html

You might want to take a look at ZeroMQ. http://zeromq.org/
Specifically, you'd want PyZMQ. http://zeromq.github.io/pyzmq/api/zmq.html
It's simple to set up, and you can connect the two computers directly. You'd be able to send messages back and forth between the two.
Definitely read the docs, but you're probably going to want a Request/Reply pattern.

Related

opponet can't apply a move in python mulitplayer Tic-Tac-Toe

so I was basically was trying to make a multiplayer Tic-Tac-Toe game but then I've been running into this following problems
This is the host side:
Enter row and column numbers to fix spot(row,column): 1,2
- X -
- - -
- - -
This is the guest side:
X - -
- - -
- - -
The problems are:
It did not pass the turn to the guest side.
It displays a false mark
on the grid.
import socket
import threading
HOST = '192.168.1.115'
PORT = 9090
class TicTacToe:
def __init__(self):
self.you = 'O'
self.opponet = 'X'
self.turn = 'X'
self.board = []
self.game_over = False
self.winner = None
self.counter = 0
self.create_board()
def create_board(self):
for i in range(3):
row = []
for j in range(3):
row.append('-')
self.board.append(row)
def show_board(self):
for row in self.board:
for item in row:
print(item, end=" ")
print()
def is_board_filled(self):
for row in self.board:
for item in row:
if item == '-':
return False
return True
def fix_move(self, row, col, player):
if self.game_over:
return
self.counter +=1
self.board[row-1][col-1] = player
self.show_board()
if self.is_player_win(player):
if self.winner == self.you:
print('You win!')
exit()
if self.winner == self.opponet:
print('You lose!')
exit()
else:
if self.counter == 9:
print('Its a draw!')
exit()
def valid_move(self, row, col):
if self.board[row][col] == 'O' or self.board[row][col] == 'X':
return False
return True
def swap_player_turn(self):
self.turn = self.you if self.turn == self.opponet else self.opponet
def handle(self, client):
while not self.game_over:
if self.turn == self.you:
move = input("Enter row and column numbers to fix spot(row,column): ")
place = move.split(',')
if self.valid_move(int(place[0]), int(place[1])):
self.fix_move(int(place[0]), int(place[1]), self.you)
self.turn = self.opponet
client.send(move.encode('utf-8'))
else:
print('Invalid Move!')
else:
data = client.recv(1024)
if not data:
client.close()
break
else:
place = data.decode('utf-8').split(',')
self.fix_move(int(place[0]), int(place[0]), self.opponet)
client.close()
def is_player_win(self, player):
if self.board[0][0] == self.board[0][1] == self.board[0][2] == 'X':
return True
if self.board[1][0] == self.board[1][1] == self.board[1][2] == 'X' or 'O':
return True
if self.board[2][0] == self.board[2][1] == self.board[2][2] == 'X' or 'O':
return True
# etc etc
def host_game(self, host, port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(1)
client, addr = server.accept()
self.you = 'X'
self.opponet = 'O'
threading.Thread(target=self.handle, args=(client,)).start()
server.close()
def connect_to_game(self, host, port):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
self.you = 'O'
self.opponet = 'X'
threading.Thread(target=self.handle, args=(client,)).start()
game = TicTacToe()
game.host_game(HOST, PORT)
the structure of the code is in a way that you take the source code above and copy it and then generate 2 files, one for the host and another for the guest the difference between them is that you you use the host_game function in the host file and the connect_to_game function in the guest file.
I've tried everything I could , searching in here , googling and nothing
I've also tried to ask ChatGPT but it was worthless
I'll address the immediate two problems:
Use your swap_player_turn() method and place it at the bottom of the while loop in handle so it happens on both host and client after the turn is handled. This will pass the turn correctly.
After asking for input or receiving data, call a common a function to convert to 0-based row/col data, because sometimes you subtract one from row/col, and sometimes you don't. For example:
def parse_move(move):
return [int(n)-1 for n in move.split(',')]
move = input("Enter row and column numbers to fix spot(row,column): ")
row, col = parse_move(move)
...
data = client.recv(1024)
row, col = parse_move(move)
Then use row/col instead of int(place[n]) everywhere. This will fix the false mark.
Other issues are the code isn't complete to determine a win or draw, opponet is misspelled, and (while this slow turn-based code will probably never have the issue) TCP is not a message-based protocol, but the code assumes it is.
A useful debug feature is to make the game able to print its state. For example, add:
def __repr__(self):
return f'TicTacToe(you={self.you!r}, op={self.opponent!r}, turn={self.turn!r})'
Then print(self) at the top of the while loop.

Why am I not breaking out of a try loop with a break statement?

My code for now works as desired where the user can input a level 1-3 depending on how hard they would like it to be (1-3 being the amount of digits the numbers will have in the math equation), and then must solve math equations. Those math equations will output EEE if the answer is incorrect and everything works as planned if you correctly answer the question as it exits the function and adds one total_correct_answers variable at the bottom, then will prompt you with another equation. However, if you input an incorrect answer and then a correct answer, you will just be prompted with the same question over and over again without the try loop being truly broken out of and total_correct_answers not being incremented positively by 1. The incrementation block of code is at lines 61-65, and the equation code is lines 30-49.
import random
def main():
ten_questions()
def get_level():
while True:
try:
level_input = int(input("Level: "))
if level_input in [1,2,3]:
return level_input
except:
pass
def integer_generator(level):
if level == 1:
x = random.randint(0,9)
y = random.randint(0,9)
elif level == 2:
x = random.randint(10, 99)
y = random.randint(10, 99)
else:
x = random.randint(100, 999)
y = random.randint(100, 999)
return x, y
def question_generator(x, y):
real_answer = x + y
wrong_counter = 0
while True:
try:
answer_given = input(str(x) + " + " + str(y) + " = ")
if int(answer_given) == real_answer:
if wrong_counter == 0:
return True
elif int(answer_given) == real_answer and wrong_counter != 0:
break
else:
while wrong_counter < 2:
print("EEE")
wrong_counter +=1
break
else:
print(str(x) + " + " + str(y) + " = " + str(real_answer))
print("False, that was last attempt")
break
except:
print("EEE")
pass
def ten_questions():
num_of_questions = 0
total_correct_answers = 1
my_level = get_level()
correct_answers = question_generator(*integer_generator(my_level))
while num_of_questions <= 8:
question_generator(*integer_generator(my_level))
num_of_questions +=1
if correct_answers == True:
total_correct_answers +=1
print("Score: " + str(total_correct_answers))
if __name__ == "__main__":
main()
Because of your line 36:
if int(answer_given) == real_answer: happens when someone answers correctly, wether they are right or wrong. So it enters the if, and then faces if wrong_counter == 0: which discards wrong answers. So just replace those two lines with if int(answer_given) == real_answer and wrong_counter == 0: and you are good to go.

List value being overwritten even though I am checking for it

I'm new to python and writing my first project. I'm trying to implement a check that if a space is already occupied, not to move there. I can't seem to figure out why my move_player method overwrites the index value of the board even though I am explicitly checking it (If it is O's turn and X has already been placed in the index O is trying to move to, it just overwrites it). I have tried hard coding the check for 'X' and 'O' instead of player.player as well but can't seem to figure it out. Does it have to do something with how Python works or am I implementing it wrong?
class Player:
def __init__(self, player):
self.player = player
class Board:
def __init__(self):
self.board = [[' ' for i in range(3)] for j in range(3)]
def display_board(self):
print('---------')
for row in self.board:
print('| ', end='')
for col in row:
print(f'{col} ', end='')
print('|')
print('---------')
def move_player(self, player):
try:
p1 = Player('X')
p2 = Player('O')
coordinates = [int(i) for i in input("Enter coordinates for move: ").split()]
xCoordinate = coordinates[0]
yCoordinate = coordinates[1]
if ((self.board[xCoordinate][yCoordinate] == p1.player) or
(self.board[xCoordinate][yCoordinate] == p2.player)):
print("That space is occupied, please choose another one.")
self.move_player(player)
else:
self.board[xCoordinate - 1][yCoordinate - 1] = player.player
except (ValueError, IndexError):
print("Please only enter numbers between 1 and 3.")
self.move_player(player)
def has_won(self, player):
if self.check_diagonal(player):
return True
elif self.check_across(player):
return True
elif self.check_down(player):
return True
return False
if __name__ == '__main__':
board = Board()
player1 = Player('X')
player2 = Player('O')
player = player1
while True:
board.display_board()
board.move_player(player)
if board.has_won(player):
board.display_board()
print(f'{player.player} wins!!!')
break
if player == player1:
player = player2
else:
player = player1
The code is very convoluted but from what I can see:
if ((self.board[xCoordinate][yCoordinate] == p1.player) or
(self.board[xCoordinate][yCoordinate] == p2.player)):
...
self.board[xCoordinate - 1][yCoordinate - 1] = player.player
You are checking [x,y] but assigning to [x-1,y-1].

Mastermind Python coding

Ok I have a feeling that this is a simple simple issue but I have been staring at this code for about 10 hours now.
The issue I am having is in mastermind is that once I get it to recognize that I have the correct colors in the right spot I can get it to display the right spots with X and the wrong spots with O. I need to be able to convert that so instead of X and O I need it to tell the user that he/she has 2 blacks and one white
For example: The secret code is RGYB The user enters RGOY so then Python relays "You have 2 blacks(The R and G spots) and one 1 White (The Y because it's the right color just in the wrong index) As of right now I got it to display X for the right color in the right spot and anything else it is an O
I will post what I have been working with now but today I am at my wit's end
https://pastebin.com/HKK0T7bQ
if correctColor != "XXXX":
for i in range(4):
if guess[i] == tempCode[i]:
correctColor += "X"
if guess[i] != tempCode[i] in tempCode:
correctColor += "O"
print (correctColor + "\n")
if correctColor == "XXXX":
if attempts == 1:
print ("You think you are sweet because you got it right on the first try? Play me again!")
else:
print ("Well done... You needed " + str(attempts) + " attempts to guess.")
game = False
A few comments
X and O
you use X and 0 to denote the success, it will be easier and faster to use a list or tuple or booleans for this, that way you can use sum() to count how many colors and locations were correct. Then whether you represent that with X and O or red and white pins is a matter for later
compartmentalization
Your game logic (guess input, input validation, do you want to continue, etc) is mixed with the comparison logic, so it would be best to separate the different functions of your program into different methods.
This is an fineexample to introduce object oriented programming, but is so simple it doesn't need OO, but it can help. What you need is a method which takes a series of colours and compares it to another series of colours
Standard library
Python has a very extended standard library, so a lot of stuff you want to do probably already exists
Correct colours
to count the number of letters which occur in 2 strings, you can use collections.Counter
guess = "RGOY "
solution = "RGYB"
a = collections.Counter(guess)
b = collections.Counter(solution)
a & b
Counter({'G': 1, 'R': 1, 'Y': 1})
correct_colours = sum((a & b).values())
3
So the user guessed 3 colours correctly
Correct locations
can be solved with an easy list comprehension
[g == s for g, s in zip(guess, solution)]
[True, True, False, False]
sum(g == s for g, s in zip(guess, solution))
2
so the used put 2 colours on the correct location
This is a MasterMind I made in Python. Hope you like it and it helped you! :)
import random
import time
from tkinter import *
def select_level():
global level
level = level_selector.get()
root.destroy()
root = Tk()
level_selector = Scale(root, from_=1, to=3, tickinterval=1)
level_selector.set(0)
level_selector.pack()
Button(root, text="Select a difficulty level", command=select_level).pack()
mainloop()
cpc_1_digit = 0
cpc_2_digit = 0
cpc_3_digit = 0
cpc_4_digit = 0
p_1_digit = 0
p_2_digit = 0
p_3_digit = 0
p_4_digit = 0
correct_correct = 0
correct_wrong = 0
chances = 0
if level == 1:
chances = 15
elif level == 2:
chances = 10
else:
chances = 7
cpc_1_digit = random.randint(0, 9)
while cpc_2_digit == cpc_1_digit or cpc_2_digit == cpc_3_digit or cpc_2_digit ==
cpc_4_digit:
cpc_2_digit = random.randint(0, 9)
while cpc_3_digit == cpc_1_digit or cpc_3_digit == cpc_2_digit or cpc_3_digit ==
cpc_4_digit:
cpc_3_digit = random.randint(0, 9)
while cpc_4_digit == cpc_1_digit or cpc_4_digit == cpc_2_digit or cpc_4_digit ==
cpc_3_digit:
cpc_4_digit = random.randint(0, 9)
while chances > 0:
correct_correct = 0
correct_wrong = 0
answer = input("Enter a four-digit number with different digits (e.g 1476): ")
p_1_digit = int(answer[0])
p_2_digit = int(answer[1])
p_3_digit = int(answer[2])
p_4_digit = int(answer[3])
if p_1_digit == cpc_1_digit:
correct_correct = int(correct_correct) + 1
elif p_1_digit == cpc_2_digit or p_1_digit == cpc_3_digit or p_1_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_2_digit == cpc_2_digit:
correct_correct = correct_correct + 1
elif p_2_digit == cpc_1_digit or p_2_digit == cpc_3_digit or p_2_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_3_digit == cpc_3_digit:
correct_correct = int(correct_correct) + 1
elif p_3_digit == cpc_1_digit or p_3_digit == cpc_2_digit or p_3_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_4_digit == cpc_4_digit:
correct_correct = int(correct_correct) + 1
elif p_4_digit == cpc_1_digit or p_4_digit == cpc_3_digit or p_4_digit ==
cpc_2_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
print("")
if int(correct_correct) == 4:
print("Congratsulations! You found the computer's number!")
break
elif int(correct_wrong) > 0 or int(correct_correct) >= 1 and int(correct_correct)
< 4:
print("You got " + str(correct_correct) + " correct digit(s) in the correct
place, and " + str(correct_wrong) + " correct digit(s) but in wrong place.")
elif int(correct_correct) == 0 and int(correct_wrong) == 0:
print("You didn't guess any number, try again!")
else:
raise Exception("CheckError: line 69, something went wrong with the
comparings.")
exit()
print("")
chances = chances - 1
if chances == 0:
print("You lost... The secret number was " + str(cpc_1_digit) + str(cpc_2_digit)
+ str(cpc_3_digit) + str(cpc_4_digit) + ". Try again by rerunning the program.")
time.sleep(4)

error making text based game spawn monster

I am making a text based game with my friend for a programming class, we are avoiding using object oriented stuff so please avoid those suggestions. to use the program I would normally do type "help" then I can go in any direction to move like "right", "left", "down" and "up" when I try to use those commands I get an error. this happend after I added the spawnMonster command part
#Connor and Griffin's text based adventure
import os
import random
############################
####---Variable setup---####
#########ADD COMMAND VARIATION############
#########ADD ITEM LISTS#################
commands = 1 #for debuging only please
maxHealth = 100 #Default begin health
health = 100 #Current health
mana = 0 #THERES NO MAGIC
mapS = [5, 5]
objects = {}
color = "0f"
output = "" #this is where whats happening is told to you
level = 1
canMove = 1
playerSym = "P"
# for activeQuests remember that if the value is 0 its not completed and if its 1 its completed
activeQuests = {"Journey To Riverwood": 0}
# Add new quest names above^
commandList = {"help", "legend", "color", "show inv", "quests", "console", "up", "left", "right", "down", "clear", "map"}
#Default inventory
inv = {"apple(s)":2, "shortsword":1, "gold":50,"cloth shirt":1,"pair of cloth pants":1,"pair of shoes":1}
clearedSpaces = []
##### "Name":baseDMG #####
monsters = {"Goblin":1, "Troll":3, "Bear":2, "Giant Spider": 1, "Bandit":1, "Goblin Chief":3}
###########################
###########################
##### Name:lv:monsterSpawnRate #####
zones = {"Forest":[1,90]}
#######################
#---Quest Log Stuff---#
def checkQuest():
for questn in activeQuests:
print("\n------", questn, "------")
if activeQuests[questn] == 0:
print("\nNot Complete")
else:
print("\nComplete")
######Description for quests######
if questn == "Journey To Riverwood":
print("""
Welcome to Connor and Griffins excellent adventure!
try out some of the commands like; help, quests,
color, inv or show inv. now using your new found
commands move to the city of riverwood.\n\n""")
#########################
#########################
############################
###---Scenes/Functions---###
def mapSize(x, y):
global mapS
mapS = [x, y]
####Ads point to map
def addObject(name, x, y, symbol):
objects[name] = [x, y, symbol]
legend[symbol] = name
#### Clears some variables
def roomStart():
global objects
objects = {}
global legend
legend = {"░":"Unknown area"}
global roomName
roomName = "BLANK"
def newArea():
for area in zones:
global spawnChance
spawnChance = zones[area][1]
def spawnMonster():
enemy, DMG = random.choice(monsters)
return enemy
def moveToNewSpace():
rand = random.randint(1,100)
if rand <= spawnChance:
global spawnedMonster
spawnMonster()
###Move player
def changePos(name, newx, newy):
objects[name][0] += newx
objects[name][1] += newy
global clearedSpaces
clearedSpaces.append([objects[name][0],objects[name][1]])
moveToNewSpace()
###First room
def roomBegin():
roomStart()
mapSize(15,10)
global roomName
roomName = "Forest"
newArea()
addObject("Riverwood",10,5,"R")
addObject("Griffin's House",2,2,"G")
addObject("Player",2,3,playerSym) #######Remember to make a "ChangePos" command to change the pos of the player when they move#######
clearedSpaces.append([2,3])
################### MAPPING HERE ##################
def makeMap():
print("\n------"+roomName+"------")
for y in range(mapS[1]):
line = ""
numy = y+1
for x in range(mapS[0]):
numx = x + 1
for place in objects:
if objects[place][:2] == [numx, numy]:
line += objects[place][2]
break
else:
if [numx, numy] in clearedSpaces:
line += " "
else:
line += "░"
print(line)
print("\n----Legend----\n")
for thing in legend:
print(thing + " - " + legend[thing])
############################
############################
#######################
###--- MAIN LOOP ---###
roomBegin()
while 1 == 1:
makeMap()
print("\n\n" + output + "\n\n")
print("\n\nHealth is at ",health,"/",maxHealth)
command = input("Enter action: ")
if command.lower() == "quests":
os.system("cls")
checkQuest()
elif command.lower() == "legend":
os.system("cls")
print("\n----Legend----\n")
for thing in legend:
print(thing + " - " + legend[thing])
elif command.lower() == "help":
os.system("cls")
print("\n\n------HelpMenu------\n")
for comd in commandList:
print(comd)
elif command.lower() == "color":
newc = input("new color: ")
os.system("color 0" + newc)
os.system("cls")
elif command.lower() == "show inv" or command.lower() == "inv" or command.lower() == "inventory":
os.system("cls")
print("\n------Inventory------\n")
for item in inv:
print(" ", inv[item]," ", item)
elif command.lower() == "console":
if commands == 1:
consolecmd = input("Enter a command: ")
os.system(consolecmd)
else:
print("Sorry, you dont have permition to use that command.")
elif command.lower() == "up":
if canMove == 1:
os.system("cls")
changePos("Player", 0,-1)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "down":
if canMove == 1:
os.system("cls")
changePos("Player", 0,1)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "left":
if canMove == 1:
os.system("cls")
changePos("Player", -1,0)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "right":
if canMove == 1:
os.system("cls")
output = "There are some trees here, and a small pond"
changePos("Player", 1,0)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "clear":
os.system("cls")
else:
os.system("cls")
print("Previous attempt was an invalid command, try again.")
#######END MAIN#######
######################
The random.choice function requires a sequence.
In a previous version of your code (or maybe it was code from a classmate of yours just having similar but not identical problems with similar code?), you had the monsters stored in a list, like [("Goblin", 1), ("Troll", 3), …]. For that code, random.choice works, because a list is a sequence.
But now you have a dict. And a dict is not a sequence.
You can get a list of all of the keys in a dict just by writing list(d). So, you could do this:
return random.choice(list(monsters))
But you're not actually getting any benefit from monsters being a dict from what I can tell, so why not just use a list in the first place?
monsters is a dictionary. It is being passed to random.choice(), however, random.choice() accepts a sequence as its argument (from which it randomly selects one element). This will not work for a dictionary and you will see a KeyError exception if you try.
Since you just want to return an enemy from spawnMonster() you can instead use the keys of monsters which is a list:
monsters = {"Goblin":1, "Troll":3, "Bear":2, "Giant Spider": 1, "Bandit":1, "Goblin Chief":3}
def spawnMonster():
return random.choice(monsters.keys())
Update
Since you are using Python 3 you can do this instead (also works in Python 2):
def spawnMonster():
return random.choice(tuple(monsters))

Categories

Resources