I've written a script for a very clunky version of minesweeper.
The player selects the square they want to reveal based on co-ordinates (like in chess) and the board is updated with the values showing how many mines are in the squares around the chosen co-ordinates. The player can also flag where they think a mine is, which shows up as an "f".
Unfortunately this is unreadable which makes it very slow going. So I was hoping to update the code with some colour, where all "2"s are printed in blue, all "3"s in red etc. I have all the components; I've downloaded colorama but I can't get it to work. I'm stuck with the rest.
Code that prints the initial empty grid:
difficulty_dictionaries = {
1 : {
"difficulty": "Beginner",
"x_axis": 8,
"y_axis": 8,
"mine_no": 10
},
2 : {
"difficulty": "Intermediate",
"x_axis": 16,
"y_axis": 16,
"mine_no": 40
},
3 : {
"difficulty": "Expert",
"x_axis": 26,
"y_axis": 16,
"mine_no": 98
}
}
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def set_difficulty():
print ("Please select difficulty level by entering either 1, 2 or 3 based on the corresponding difficulty")
diff_input = input ("1. Beginner: \n2. Intermediate: \n3. Expert: ")
return difficulty_dictionaries[int(diff_input)]
def set_user_board():
grid = []
grid.append(" ")
for set_x in range(diff_dict["x_axis"]):
grid.append(ALPHABET[set_x])
grid[0] = (" ".join(grid))
del grid[1:]
grid.append(" " " " ("- ")*(diff_dict["x_axis"]))
for set_y in range(diff_dict["y_axis"]):
grid.append(str(set_y 1) " |" (" " "|")*diff_dict["x_axis"]) if set_y < 9 else grid.append(str(set_y 1) "|" (" " "|")*diff_dict["x_axis"])
grid.append(" " ("- ")*diff_dict["x_axis"])
return(grid)
def print_grid():
print('\n'.join(' '.join(map(str, b)) for b in grid))
return
diff_dict = set_difficulty()
grid = set_user_board()
print_grid()
Output:
As squares are selected, the values are taken from another reference list of lists and inserted into grid
at the relevant point.
I stole the part of the code that prints the grid from another answer on SO but I don't know how it works. I have also tried this:
def print_grid():
for x in grid:
print(*x)
return
which is far more understandable. But when I try to apply the colour to the items in the list I'm encountering some problems - mostly with the *
.
def print_grid():
for x in grid:
print(f"{Fore.RED}" x)
return
That prints an all red grid - but it's squished:
CodePudding user response:
First explanations:
You have 2D grid and x
can means row with many values -
When you use print(*x) then it runs it as print(x[0], x[1], ...)
so it prints many separated elements and print()
automatically add space
between elements. You could say that every comma ,
adds space
in output.
Try print("A", "B")
and you get "A B"
instead of "AB"
When you print(f"{Fore.RED}" x)
then you print one string (probably row converted to string) and print()
doesn't know that it needs spaces
between elements. You have to format this string with spaces before using print()
It would be simpler to keep grid
as 2D grid (without converting rows to string) and use nested for
-loops `(with better names for variables)
for row in grid:
for item in row:
print(item, end=' ')
print() # go to next line
And now you can use if/else
to print it in different colors
for row in grid:
for item in row:
if item in (' ', '-', '|'): # or `if item in " -|"`
color = Fore.RED
elif item in ('1', '2', '3', '4', '5'): # or `if item in "12345"`
color = Fore.GREEN
else:
color = Fore.WHITE
print(f"{color}{item}", end=' ') # I add `space` instead of `\n` as `end`
print() # go to next line
Minimal working example:
from colorama import Fore, Back, Style
grid = [
[' ', '-', ' ', '-', ' ', '-', ' '],
['|', '1', '|', ' ', '|', ' ', '|'],
[' ', '-', ' ', '-', ' ', '-', ' '],
['|', 'X', '|', '2', '|', ' ', '|'],
[' ', '-', ' ', '-', ' ', '-', ' '],
['|', ' ', '|', 'O', '|', '3', '|'],
[' ', '-', ' ', '-', ' ', '-', ' '],
]
# ---
# letters
print(end=' ')
for item in 'ABC':
print(f" {Fore.WHITE Style.BRIGHT}{item} ", end=' ')
print()
# rows
for number, row in enumerate(grid, 1):
# row's number
if number % 2 == 1:
print(" ", end='')
else:
print(f"{Fore.WHITE Style.BRIGHT}{number//2} ", end='')
# row's grid
for item in row:
if item in (' ', '-', '|'): # or `if item in " -|"`
color = Fore.RED Style.BRIGHT
elif item in ('1', '2', '3', '4', '5'): # or `if item in "12345"`
color = Fore.GREEN Style.BRIGHT
elif item in ('X', 'O'): # or `if item in "12345"`
color = Fore.BLUE Style.BRIGHT
else:
color = Fore.WHITE Style.BRIGHT
print(f"{color}{item}", end=' ') # I add space at the end of `f-string`
print() # go to next line
Result (with colors) in console:
EDIT:
I made more universal version which use grid
without lines -
from colorama import Fore, Back, Style
import string
grid = [
['1', 'D', ' ', 'A', '4'],
['E', '2', '5', ' ', 'B'],
['6', 'F', '3', 'C', ' '],
]
# ---
HEIGTH = len(grid)
WIDTH = len(grid[0])
LETTERS = string.ascii_uppercase[:WIDTH]
# --- columns letters ---
print(end=' ')
for item in LETTERS:
print(f' {Fore.WHITE Style.BRIGHT}{item} ', end='')
print()
# --- rows ---
for number, row in enumerate(grid, 1):
# top line
print(f'{Fore.RED Style.BRIGHT} ' ' - '*WIDTH)
# row with data
# number
print(f'{Fore.WHITE Style.BRIGHT}{number} ', end='')
# first left line
print(f'{Fore.RED Style.BRIGHT}| ', end='')
# data with right line
for item in row:
if item in '123':
color = Fore.GREEN Style.BRIGHT
elif item in '456':
color = Fore.YELLOW Style.BRIGHT
elif item in 'ABCDEF': # or `if item in "12345"`
color = Fore.BLUE Style.BRIGHT
else:
color = Fore.WHITE Style.BRIGHT
print(f"{color}{item} {Fore.RED Style.BRIGHT}| ", end='') # I add space at the end of `f-string`
print() # go to next line
# --- last (bottom) line ---
print(f'{Fore.RED Style.BRIGHT} ' ' - '*WIDTH)
Result (with colors) in console: