I'm trying to generate a large tile map which is then going to be displayed on the screen. The map should be random, and only consists of two types of tiles at the moment.
However, what happens now is that each row of the Tile Map is overwritten with the first row from the heightmap, so that my map displays straight line columns of similar tiles when it displays.
I believe this is due to how I wrote my for loops, where it iterates through the entire heightmap, before even reaching the second list of tiles. Although due to the somewhat random element of tile choice that I tried to include, there should be at least some noise introduced to the map, but it seems like there isn't any.
Here is a link to a screenshot of what displays when I run my code.
import pygame, random
class Map(object):
MAPWIDTH = 64
MAPHEIGHT = 48
HEIGHTS = [0, 1, 2, 3, 4, 5, 6, 7, 8]
def __init__(self):
self.heightmap = [[random.choice(self.HEIGHTS) for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
self.Tiles = [['' for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
for rows in self.Tiles:
for row in self.heightmap:
i = 0
for height in row:
# 100% water block
if height == 0:
rows[i] = 'WATER'
# 70% water block
if height == range(1, 3):
if random.randint(0, 9) == range(0, 6):
rows[i] = 'WATER'
else:
rows[i] = 'GRASS'
# 50% water block
if height == 4:
if random.random() == 0:
rows[i] = 'WATER'
else:
rows[i] = 'GRASS'
# 80% grass block
if height == range(5, 7):
if random.randint(0, 9) == range(0, 6):
rows[i] = 'GRASS'
else:
rows[i] = 'WATER'
# 100% grass block
if height == 8:
rows[i] = 'GRASS'
i += 1
You write a lot of lines like:
if height == range(1, 3):
but that does not do what you think it does.
range(1, 3) returns the list [1, 2] (or an iterable that yields 1 and 2 if you're using python3), and that is never equal to a single integer.
You probably want to use a pattern like:
if height == 1 or height == 2
or
if 1 <= height <= 2:
or
if height in range(1, 2):
Nonetheless, you could simplify your code by creating a helper function that returns the chance of a grass tile for a given height:
def chance_of_grass(height):
if height == 0: return 0
elif height <= 3: return 30
elif height <= 4: return 50
elif height <= 7: return 80
return 100
and call that in your loop:
def __init__(self):
self.heightmap = [[random.choice(self.HEIGHTS) for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
self.Tiles = [['' for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
r_i = 0 # index of row
for h_row in self.heightmap:
c_i = 0 # index of column
for height in row:
is_grass = change_of_grass(height) >= random.randint(1, 100)
self.Tiles[r_i][c_i] = 'GRASS' if is_grass else 'WATER'
c_i += 1
r_i += 1
self.heightmap = [[random.choice(self.HEIGHTS) for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
self.Tiles = [['' for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
I'm not entirely sure what you're trying to do with that ^ but try this:
self.heightmap=[]
self.Tiles=[]
q=[]
for w in range(self.MAPWIDTH):
for h in range(self.MAPHEIGHT): q.append(random.choice(self.HEIGHTS))
self.heightmap.append(q)
q=[]
for w in range(self.MAPWIDTH):
for h in range(self.MAPHEIGHT): q.append('')
self.Tiles.append(q)
q=[]
for rows in self.Tiles:
for row in self.heightmap:
i = 0
for height in row:
rows.pop(i)
# 100% water block
if height == 0:
rows.insert(i,'WATER')
# 70% water block
if height in range(1, 3):
if random.randint(0, 9) in range(0, 6):
rows.insert(i,'WATER')
else:
rows.insert(i,'GRASS')
# 50% water block
if height == 4:
if random.random() > 0.5:
rows.insert(i,'WATER')
else:
rows.insert(i,'GRASS')
# 80% grass block
if height in range(5, 7):
if random.randint(0, 9) in range(0, 6):
rows.insert(i,'GRASS')
else:
rows.insert(i,'WATER')
# 100% grass block
if height == 8:
rows.insert(i,'GRASS')
i += 1
Related
I recently tried to code an AI to solve the connect-four game. I've come quite far but I am now stuck with a minor mistake in the code that I just cant locate. Generally the algorithm played great but sometimes the algorithms ignores a row of 3 pieces the opponent has which results in the loss of the algorithm. As you will see, I have constructed the evaluation function so that positions like that should be rated with a extremely low score, which it does. Also the score of a position where the algorithm has lost is always rated with -inf. Therefore I can't imagine why the algorithm would be unable to counter positions like that.
The bot relies on a framework which I can't upload here thus I am sorry that the code itself without changes cant be simply executed.
from aiagent import AiAgent
import math
import copy
import numpy as np
class MinMaxAgent(AiAgent):
def __init__(self):
'''
Creates the board.
'''
self.board = [[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0]]
def getNextMove(self):
'''
Calculate the index of the player move and store it on the board. Return that value.
'''
self._getMinMax(board=self.board)
self.board[self.bestIndexCol][self._getRowIndex(self.bestIndexCol, self.board)] = 1
print(f'Eval: {self._evaluate(self.board)}')
return (self.bestIndexCol, self._getRowIndex(self.bestIndexCol, self.board))
def handleNextMove(self, indexCol):
'''
Store the index of the enemy move in the board.
'''
self.board[indexCol[0]][self._getRowIndex(indexCol[0], self.board)] = -1
print(f'Eval: {self._evaluate(self.board)}')
def _getRowIndex(self, indexCol, board):
'''
Get the index of the row of a column within a board.
'''
for indexRow, elementRow in enumerate(board[indexCol]):
if elementRow == 0:
return indexRow
def _getValidIndex(self, board):
'''
Get all the valid indices of a board.
'''
validMoves = []
for indexCol, col in enumerate(board):
if col.count(0) != 0:
validMoves.append(indexCol)
return validMoves
def _getMinMax(self, board, depth=6, player=1, alpha=-math.inf, beta=math.inf):
'''
Calculates the best move within a specific depth.
'''
if depth == 0:
return self._evaluate(board)
elif self._isTerminalState(board) == 0:
return self._evaluate(board)
elif self._isTerminalState(board) == -1:
return -math.inf
elif self._isTerminalState(board) == 1:
return math.inf
if player == 1:
resultMax = -math.inf
self.bestIndexCol = None
for indexCol in self._getValidIndex(board):
# Mutate the board
self.nextBoard = copy.deepcopy(board)
self.nextBoard[indexCol][self._getRowIndex(indexCol, board)] = 1
# Calls itself with a by one decremented depth and the change of player
self.resultMinMax = self._getMinMax(board=self.nextBoard, depth=depth-1, player=-1, alpha=alpha, beta=beta)
# Take the board state with the most amount of points
if self.resultMinMax > resultMax:
resultMax = self.resultMinMax
self.bestIndexCol = indexCol
# Change alpha if the boardstate is evaluated with more points
if self.resultMinMax > alpha:
alpha = self.resultMinMax
# Break the loop if on a alphaboundry
if alpha >= beta:
break
return resultMax
elif player == -1:
resultMin = math.inf
for indexCol in self._getValidIndex(board):
# Mutate the board
self.nextBoard = copy.deepcopy(board)
self.nextBoard[indexCol][self._getRowIndex(indexCol, board)] = -1
# Calls itself with a by one decremented depth and the change of player
self.resultMinMax = self._getMinMax(board=self.nextBoard, depth=depth-1, player=1, alpha=alpha, beta=beta)
# Take the board state with the least amount of points
if self.resultMinMax < resultMin:
resultMin = self.resultMinMax
# Change beta if the boardstate is evaluated with less points
if self.resultMinMax < beta:
beta = self.resultMinMax
# Break the loop if on a betaboundry
if alpha >= beta:
break
return resultMin
def _isTerminalState(self, board):
'''
Checks the board for a terminal state of the board:
Return: 0 for a draw;
1 for a victory;
-1 for a defeat;
'''
# Evaluate draw
if [board[col].count(0) for col in range(7)] == [0,0,0,0,0,0,0]:
return 0
# Evaluate vertical for terminal state
for col in range(7): # columns
for row in range(3): # rows
if [board[col][row + i] for i in range(4)] == [1,1,1,1]:
return 1
elif [board[col][row + i] for i in range(4)] == [-1,-1,-1,-1]:
return -1
# Evaluate horizontal for terminal state
for col in range(4): # columns
for row in range(6): # rows
if [board[col + i][row] for i in range(4)] == [1,1,1,1]:
return 1
elif [board[col + i][row] for i in range(4)] == [-1,-1,-1,-1]:
return -1
# Evaluate diagonal for terminal state
for col in range(4): # columns
for row in range(3): # rows
if [board[col + i][row + i] for i in range(4)] == [1,1,1,1]:
return 1
elif [board[col + i][row + i] for i in range(4)] == [-1,-1,-1,-1]:
return -1
for col in range(4): # columns
for row in range(3, 6): # rows
if [board[col + i][row - i] for i in range(4)] == [1,1,1,1]:
return 1
elif [board[col + i][row - i] for i in range(4)] == [-1,-1,-1,-1]:
return -1
def _evaluateSection(self, section):
'''
Evaluates every section of the board and adds points according to the amount of elements of the same actor in a section:
PLAYER: 4-in-a-row: +inf
ENEMY: 4-in-a-row: -inf
PLAYER: 3-in-a-row: +1000
ENEMY: 3-in-a-row: -3000
PLAYER: 2-in-a-row: +200
ENEMY: 2-in-a-row: -600
'''
self.section_evaluation = 0
if section.count(1) == 4:
self.section_evaluation += math.inf
elif section.count(-1) == 4:
self.section_evaluation -= math.inf
elif section.count(1) == 3 and section.count(0) == 1:
self.section_evaluation += 1000
elif section.count(-1) == 3 and section.count(0) == 1:
self.section_evaluation -= 3000
elif section.count(1) == 2 and section.count(0) == 2:
self.section_evaluation += 200
elif section.count(-1) == 2 and section.count(0) == 2:
self.section_evaluation -= 600
return self.section_evaluation
def _evaluate(self, board):
'''
Takes sections of the board to evaluate.
'''
self.evaluation = 0
# Evaluate vertical sections
for col in range(7): # columns
for row in range(3): # rows
self.section = [board[col][row + i] for i in range(4)]
self.evaluation += self._evaluateSection(self.section)
# Evaluate horizontal sections
for col in range(4): # columns
for row in range(6): # rows
self.section = [board[col + i][row] for i in range(4)]
self.evaluation += self._evaluateSection(self.section)
# Evaluate diagonal sections
for col in range(4): # columns
for row in range(3): # rows
self.section = [board[col + i][row + i] for i in range(4)]
self.evaluation += self._evaluateSection(self.section)
for col in range(4): # columns
for row in range(3, 6): # rows
self.section = [board[col + i][row - i] for i in range(4)]
self.evaluation += self._evaluateSection(self.section)
return self.evaluation
I already redesigned the evaluation function and checked the minmax-algorithm which should include all the possible sources of this error but I wasn't able to find any satisfying answer.
I've been trying to figure out why when I run the GUI of the board, all the colors slowly start turning into one color over time such as green, brown, pink, etc. Also, when I put 3 cells in a row they disappear instead of looping infinitely. This is the board class responsible for updating and checking everything on the board. I've tried many different ways but still end in the same result. I'm relatively new to coding so any help would be appreciated!
class Board:
def __init__(self, size=20):
self._board = [[(0, 0, 0) for _ in range(size)] for _ in range(size)]
self._prior = copy.deepcopy(self._board)
def get_board(self):
return self._board
def change_color(self, i, j):
r, g, b = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
self._board[i][j] = (r, g, b)
def count_neighbors(self, i, j):
num_neighbors = 0
total_r = 0
total_g = 0
total_b = 0
for x in range(i - 1, i + 2):
for y in range(j - 1, j + 2):
if 0 <= x < len(self._board) and 0 <= y < len(self._board[i]):
if (x, y) != (i, j) and self._board[x][y] != (0, 0, 0):
num_neighbors += 1
total_r += self._board[x][y][0]
total_g += self._board[x][y][1]
total_b += self._board[x][y][2]
if num_neighbors > 0:
average_color = (total_r // num_neighbors, total_g // num_neighbors, total_b // num_neighbors)
else:
num_neighbors = 0
average_color = (0, 0, 0)
return num_neighbors, average_color
def update(self):
self._prior = copy.deepcopy(self._board)
for i in range(len(self._prior)):
for j in range(len(self._prior[i])):
num_neighbors, average_color = self.count_neighbors(i, j)
if self._board[i][j] != (0, 0, 0):
if num_neighbors < 2 or num_neighbors > 3:
self._board[i][j] = (0, 0, 0)
elif num_neighbors == 3:
self._board[i][j] = average_color
if random.randint(1, 100) == 42:
x = random.randint(0, len(self._board) - 1)
y = random.randint(0, len(self._board) - 1)
self.change_color(x, y)
I'm making a game in which the player can move on a 8x8 grid, but I'm getting an error in which the values are out of range.
Here is my code:
def player_movement():
grid0 = []
grid1 = []
i = 0
n = 0
while i < 8: #this makes the grid
grid0.append("0")
i += 1
while n < 8:
grid1.append(grid0.copy())
n += 1
grid1[0][0] = "X" # this places the player on the top left of the grid
for l in grid1:
print(l)
while True:
player_movex = int(input("Move right how many?"))# instructions to move the player
player_movey = int(input("Move down how many??"))
for y, row in enumerate(grid1): #this finds the player on the grid
for x, i in enumerate(row):
if i == "X":
grid1[y][x], grid1[y + player_movey][x + player_movex] = grid1[y + player_movey][x + player_movex], grid1[y][x]
for j in grid1: #prints out the grid in the 8x8 format
print(j)
and I am entering values that are within the lists' range i.e. 0-7.
This is the error that appears on my screen:
Traceback (most recent call last):
File "D:\Python\Treasure Hunt game.py", line 83, in <module>
player_movement()
File "D:\Python\Treasure Hunt game.py", line 78, in player_movement
grid1[y][x], grid1[y + player_movey][x + player_movex] = grid1[y + player_movey][x + player_movex], grid1[y][x]
IndexError: list index out of range
The reason being the loops are executed even after the movement is made.
def player_movement():
grid0 = []
grid1 = []
i = 0
n = 0
while i < 8: #this makes the grid
grid0.append("0")
i += 1
while n < 8:
grid1.append(grid0.copy())
n += 1
grid1[0][0] = "X" # this places the player on the top left of the grid
for l in grid1:
print(l)
while True:
player_movex = int(input("Move right how many?"))# instructions to move the player
player_movey = int(input("Move down how many??"))
done = False
for y, row in enumerate(grid1): #this finds the player on the grid
for x, i in enumerate(row):
if i == "X":
print(y, x)
grid1[y][x], grid1[y + player_movey][x + player_movex] = "0", "X"
done = True
if done == True:
break
if done == True:
break
for j in grid1: #prints out the grid in the 8x8 format
print(j)
player_movement();
I would rather code as follows:
def player_movement():
n = 8
grid = [['0'] * n for _ in range(n)]
m = 'x'
grid[0][0] = m # this places the player on the top left of the grid
for i in grid:
print(i)
while True:
# instructions to move the player
player_movex = int(input("Move right how many? "))
player_movey = int(input("Move down how many?? "))
move(grid, m, n, player_movey, player_movex)
for j in grid: # prints out the grid in the 8x8 format
print(j)
def move(grid, m, n, move_y, move_x):
for y, row in enumerate(grid): # this finds the player on the grid
for x, i in enumerate(row):
if i == m:
a, b = y + move_y, x + move_x
if a >= n:
print(f'Sorry, move {move_y} down will out of range!\n')
return
if b >= n:
print(f'Sorry, move {move_x} right will out of range!\n')
return
grid[y][x], grid[a][b] = grid[a][b], grid[y][x]
return
player_movement()
I'm currently working on making a Game of Life program (UNI related, beginner course), by using nested lists.
However I can't seem to get the update() method to work properly, I've no clue what's wrong. The generation of the first board is okay, but the update leaves only the cornercells alive, and the rest dead.
All methodcalls in this class originates from other .py files, which works well.
from random import randint
from cell import *
class Spillebrett:
def __init__(self, rows, columns):
self.genNumber = 0
self._rows = rows
self._columns = columns
self._grid = []
for i in range(self._rows):
self._grid.append([])
for j in range(self._columns):
self._grid[i].append(cell())
self.generate()
def drawBoard(self):
for i in self._grid:
print(" ".join(map(str, i)))
print()
#Method updates genNumber, checks if cells are alive or dead and updates the board accordingly
#Currently only yield board with corner-cells alive
def updateBoard(self):
self.genNumber += 1
toLive = []
toDie = []
for x, row in enumerate(self._grid):
for y, cell in enumerate(rad):
if cell.areAlive() is True:
counter = len(self.findNeighbour(x, y))
if counter < 2 or counter > 3:
toDie.append(cell)
elif counter == 2 or counter == 3:
toLive.append(cell)
elif cell.areAlive() is False:
counter = len(self.findNeighbour(x, y))
if counter == 3:
toLive.append(cell)
for i in toDie:
i.setDead()
for i in toLive:
i.setAlive()
return self.genNumber
#Code given by Uni
def generate(self):
for i in range(self._rows):
for j in range(self._columns):
rand = randint(0, 3)
if rand == 3:
self._grid[i][j].setAlive()
#Code given by Uni
def findNeighbour(self, row, column):
neighbourList = []
for i in range(-1, 2):
for j in range(-1, 2):
neighbourRow = rad + i
neighbourcolumn = column + j
if(neighbourRow == rad and neighbourcolumn == column) is not True:
if(neighbourRow < 0 or neighbourcolumn < 0 or neighbourRow >
self._rows - 1 or neighbourcolumn > self._columns - 1) is not True:
neighbourList.append(self._grid[neighbourRow][neighbourcolumn])
return neighbourList
def findAllAlive(self):
self._alive = 0
for i in range(self._rows):
for j in range(self._columns):
if self._grid[i][j].areAlive() is True:
self._alive += 1
return self._alive
So I am programming a checkers game, and the problem I am having is with creating several pieces in a loop. I have the class creation part of the code, which I won't post here, and the rest, which I'm posting, but I don't know how to change the variable the loop is about to use. If you can lend me a hand and clear this out, I would be thankful.
Sorry for posting my code as image, I'm new to this website ( and programming) and couldn't format so that the website would accept my post. I really hope it's ok for you guys to help me!
Thanks for the help!
Further clarification: I need to use a different "piece" creation everytime the loop runs. That means the first loop has to create piece1, then piece2, then piece3... and so forward
EDIT: Posting whole code. I know format is wrong, can't help it. So, hope somebody can fix it.
class Piece:
def __init__(self, kind, yposition, xposition):
self.color = kind
self.ypos = xposition
self.xpos = yposition
def getColor(self):
return self.getColor
def adjustY(self, change):
self.ypos = self.ypos + change
def adjustX(self, change):
self.xpos = self.xpos + change
def getY(self):
return self.ypos
def getX(self):
return self.xpos
def mover(self, direction):
self.direc = direction
if self.direc == "right" and self.color == "white":
for n in alist:
if n.getY == (self.getY - 1) and n.getX == (self.getX + 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(-1)
self.adjustX(+1)
elif self.direc == "left" and self.color == "white":
for n in alist:
if n.getY == (self.getY - 1) and n.getX == (self.getX - 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(-1)
self.adjustX(-1)
elif self.direc == "right" and self.color == "black":
for n in alist:
if n.getY == (self.getY + 1) and n.getX == (self.getX + 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(+1)
self.adjustX(+1)
else:
for n in alist:
if n.getY == (self.getY + 1) and n.getX == (self.getX - 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(+1)
self.adjustX(-1)
piece1 = 0
piece2 = 0
piece3 = 0
piece4 = 0
piece5 = 0
piece6 = 0
piece7 = 0
piece8 = 0
piece9 = 0
piece10 = 0
piece11 = 0
piece12 = 0
alistb1 = [piece1,piece2,piece3,piece4,piece5,piece6,piece7,piece8,piece9,piece10,piece11,piece12]
k = 2
for i in range(0,11):
if i >= 0 and i <5:
j = 8
m = 0
elif i >= 5 and i < 9:
j = 7
m = 1
else:
j = 6
m = 0
alistb1[i] = Piece("white",j,(m + 1 + i * k))
print(alistb1[i].getY())
# print(piece7.getY()) test reasons
PS: def mover is not ready yet.
You do not need to assign a variable for each piece. You are already using a list for your pieces. Instead of writing piece1, you can just write pieces[0]. (You do need to note that lists start with index 0.)
range has an exclusive right bound. This means that it is not included, your range ends with one less than that value. You want to use range(0,12).
In python, you can add to lists dynamically. You do not need to allocate enough spaces to fit your pieces. You can use the .append() method of lists.
One way to write your code now is this:
pieces = []
for i in range(0, 12): # 0-11
if i < 5:
pieces.append(Piece("white", 8, 1 + i*2))
elif i < 9:
pieces.append(Piece("white", 7, 2 + i*2))
else:
pieces.append(Piece("white", 6, 1 + i*2))
I took the liberty of simplifying your conditional statements (i will always be >= 0 and if i < 5 is false, then the inverse, i >= 5, is true, so you don't need to restate it in your elif) and getting rid of j, k, and m which are unnecessary variables and can be replaced with literals to save memory.
One more thing: your implementation of getColor will return the function object itself. I think you wanted to do:
def getColor():
return self.color
Use a dictionary and a for loop:
pieces = {}
# I'm assuming you want 12 pieces since your list has 12 pieces
for i in range(1,13): # range starts at m so, range(m,n) iterates from m up to n-1
# I would suggest using more descriptive variable names if you can, row or column for example
if i >= 0 and i <5:
j = 8
m = 0
elif i >= 5 and i < 9:
j = 7
m = 1
else:
j = 6
m = 0
pieces['piece{}'.format(i)] = Piece("white",j,(m + 1 + i * k))
This should do what you want unless I am misunderstanding you. Also this isn't C++ you don't need those get methods you can simply Piece.color to get the color attribute of a piece.
Use the dictionary to access the pieces, pieces['piece1'].whatever(). However for brevity's sake you don't need to pieces['piece{}.format(i)] you can just pieces[i] and the piece would be accessed pieces[1].whatever().
More info on dictionaries http://docs.python.org/3.3/tutorial/datastructures.html#dictionaries
What I have and it works with no errors:
class Piece:
def __init__(self, kind, yposition, xposition):
self.color = kind
self.ypos = xposition
self.xpos = yposition
def getColor(self):
return self.getColor
def adjustY(self, change):
self.ypos = self.ypos + change
def adjustX(self, change):
self.xpos = self.xpos + change
def getY(self):
return self.ypos
def getX(self):
return self.xpos
def mover(self, direction):
self.direc = direction
if self.direc == "right" and self.color == "white":
for n in alist:
if n.getY == (self.getY - 1) and n.getX == (self.getX + 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(-1)
self.adjustX(+1)
elif self.direc == "left" and self.color == "white":
for n in alist:
if n.getY == (self.getY - 1) and n.getX == (self.getX - 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(-1)
self.adjustX(-1)
elif self.direc == "right" and self.color == "black":
for n in alist:
if n.getY == (self.getY + 1) and n.getX == (self.getX + 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(+1)
self.adjustX(+1)
else:
for n in alist:
if n.getY == (self.getY + 1) and n.getX == (self.getX - 1):
pass
# NOT YET IMPLEMENTED
else:
self.adjustY(+1)
self.adjustX(-1)
k=2
pieces = {}
# I'm assuming you want 12 pieces since your list has 12 pieces
for i in range(1,13): # range starts at m so, range(m,n) iterates from m up to n-1
# I would suggest using more descriptive variable names if you can, row or column for example
if i >= 0 and i <5:
j = 8
m = 0
elif i >= 5 and i < 9:
j = 7
m = 1
else:
j = 6
m = 0
pieces['piece{}'.format(i)] = Piece("white",j,(m + 1 + i * k))
Output:
>>> pieces['piece1'].color
'white'
>>> pieces['piece3'].color
'white'
>>> pieces['piece3'].xpos
8
>>> for key in pieces:
print(key, pieces[key])
piece8 <__main__.Piece object at 0x000000000329A4E0>
piece9 <__main__.Piece object at 0x000000000329A550>
piece6 <__main__.Piece object at 0x000000000329A400>
piece7 <__main__.Piece object at 0x000000000329A470>
piece4 <__main__.Piece object at 0x000000000329A320>
piece5 <__main__.Piece object at 0x000000000329A390>
piece2 <__main__.Piece object at 0x0000000003287DA0>
piece3 <__main__.Piece object at 0x000000000329A2B0>
piece1 <__main__.Piece object at 0x00000000031D9CF8>
piece10 <__main__.Piece object at 0x000000000329A5C0>
piece11 <__main__.Piece object at 0x000000000329A630>
piece12 <__main__.Piece object at 0x000000000329A6A0>
>>> pieces['piece3'].mover('right')
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
pieces['piece3'].mover('right')
File "C:/Users/Hannah/Documents/thing.py", line 25, in mover
for n in alist:
NameError: global name 'alist' is not defined
>>> pieces['piece3'].xpos
8
>>> pieces['piece3'].adjustX(1)
>>> pieces['piece3'].xpos
9
Keep in mind dictionaries are unordered so the order they print in is arbitrary.
The traceback on mover is expected since I don't have alist in my version of the code. You will need to modify mover() to work with the dictionary. Some helpful ways to work with dicts:
>>> for n in pieces.values(): # iterates over the values in a dict
n.color
'white'
'white'
'white'
'white'
'white'
'white'
'white'
'white'
'white'
'white'
'white'
'white'
>>> for n in pieces.keys(): # iterates over the keys
print(n)
piece8
piece9
piece6
piece7
piece4
piece5
piece2
piece3
piece1
piece10
piece11
piece12