1

So I found some code that formatted a 2048 Game Board so that it didn't look messy when there was more than 1 digit to a number:

nlist = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 128, 2, 2, 16, 16]
widths = [max(len(str(nlist[row * 4 + col])) for row in range(4)) + 2 for col in range(4)]
width = sum(widths) + 5
count = 0
for i in range(16):
    print('|{:^{width}}'.format(nlist[i], width=widths[i % 4]), end = '')
    count += 1
    if count == 4:
        print("|\n" + '-' * width)
        count = 0
print("")

Run this code to make things more clear and change values of nlist to see how the formatting works. So anyways, after I finished the game, I wanted to add colors to make the game easier to understand in terminal so I edited my code to look like this:

clist = nlist.copy()
for x in range(16):
    if clist[x] == 2:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 4:
        clist[x] = ' \033[1;37;105m' + str(clist[x]) + '\033[0m '
    if clist[x] == 8:
        clist[x] = ' \033[1;37;104m' + str(clist[x]) + '\033[0m '
    if clist[x] == 16:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 32:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 64:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 128:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 256:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 512:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 1024:
    clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 2048:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
    if clist[x] == 4096:
        clist[x] = ' \033[1;37;106m' + str(clist[x]) + '\033[0m '
widths = [max(len(str(nlist[row * 4 + col])) for row in range(4)) + 2 for 
col in range(4)]
width = sum(widths) + 5
count = 0
for i in range(16):
    print('|{:^{width}}'.format(clist[i], width=widths[i % 4]), end = '')
    count += 1
    if count == 4:
        print("|\n" + '-' * width)
        count = 0

But now the formatting got all messed up and my board looked ugly once again. Is there a possible way to change this code so that it looks like the first code except with colors(right now almost all the colors are the same for times sake. I will change it later). Also, is there any easier way to put colors in a conditional statement?

EDIT:

This is the link to the file with no colors that formats correctly: 2048 that works(no colors)

This is the link to the file with colors that does not format correctly: 2048 that does not work(colors)

Screen shot of me running code: Screen shot of messed up format

3
  • Adding (proper) ANSI escape sequences should not be changing the number of visible characters. Therefore, your count must be off. This is the first time I've asked this on Stack Overflow: can you add a screenshot of your colored text? Commented Jul 20, 2018 at 22:09
  • I will put a link into my whole code in the description Commented Jul 21, 2018 at 0:06
  • @J.Doe, Updated, hope it help you. Commented Jul 21, 2018 at 11:58

2 Answers 2

3

There're two reasons why your colour coding get messed up.

1) You did not define the colour coding for 0, therefore there is always a big formatting gap for zero with other numbers in your code.

2) Your width function did not change with colour function but actually the string length for colored output is much more larger than without one. Therefore I suggest you use a constant number, like 22 or something bigger in your code. Alternately, you can change

widths = [max(len(str(nlist[row * 4 + col])) for row in range(4)) + 2 for col in range(4)]

to

widths = [max(len(str(nlist[row * 4 + col]))+21 for row in range(4)) + 2 for col in range(4)]

To simplify the if structure, I suggest you use a dictionary to lookup for the desired color:

example:

WHITE_COLOR = "#ffffff"
BACKGROUND_COLOR_GAME = "#92877d"
BACKGROUND_COLOR_CELL_EMPTY = "#9e948a"
BACKGROUND_COLOR_DICT = {   2:"#eee4da", 4:"#ede0c8", 8:"#f2b179", 16:"#f59563", \
                            32:"#f67c5f", 64:"#f65e3b", 128:"#edcf72", 256:"#edcc61", \
                            512:"#edc850", 1024:"#edc53f", 2048:"#edc22e" }
CELL_COLOR_DICT = { 2:"#776e65", 4:"#776e65", 8:"#f9f6f2", 16:"#f9f6f2", \
                    32:"#f9f6f2", 64:"#f9f6f2", 128:"#f9f6f2", 256:"#f9f6f2", \
                    512:"#f9f6f2", 1024:"#f9f6f2", 2048:"#f9f6f2" }
FONT = ("Verdana", 40, "bold")
SCORE_FONT=("Verdana", 20, "bold")

For your code, you can make it like

nlist = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 128, 2, 2, 16, 16]
color_dict = {0:' \033[1;37;106m0\033[0m ',
              2:' \033[1;37;106m2\033[0m ',4:' \033[1;37;104m4\033[0m ',
              8:' \033[1;37;106m8\033[0m ',16:' \033[1;37;106m16\033[0m ',
              32:' \033[1;37;106m32\033[0m ',64:' \033[1;37;106m64\033[0m ',
              128:' \033[1;37;106m128\033[0m ',256:' \033[1;37;106m256\033[0m ',
              512:' \033[1;37;106m512\033[0m ',1024:' \033[1;37;106m1024\033[0m ',
              2048:' \033[1;37;106m2048\033[0m ',4096:' \033[1;37;106m4096\033[0m '}
count = 0
for i in range(16):
    print('|{:^{width}}'.format(color_dict[nlist[i]], width=22), end = '')   #This line is modified.
    count += 1
    if count == 4:
        print("|\n" + '-')
        count = 0
Sign up to request clarification or add additional context in comments.

13 Comments

How can I incorporate this into my code(I have never used dictionaries before?
@ J.Doe, I have no idea how you can achieve color coding in python without import any module. In the link provided above, tkinter module is deployed, and the color is referenced from the dictionary provided above. Example: if score=2. Color=BACKGROUND_COLOR_DICT[score]. Color is "#eee4da", which is grey. color-hex.com/color/eee4da
I never said I can't import anything but how does this work in my conditional statement without the formatting getting messed up
@Marcus.Aurelianus He wants colour formatting in the terminal output, not in a GUI application. He already showed in the question how that can be done (with ANSI escape sequences). When I understand the question right, the user wants to know how he can use it without messing up the printed grid formatting.
@J. Doe, I suspect the color of your table is messed up because they all use one color '\e[0;106m'.
|
0

Use colored from termcolor modules for colors

from termcolor import colored
nlist = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 128, 2, 2, 16, 16]
color = {n:'cyan' for n in nlist}
color[4] = 'red'

widths = [max(len(str(nlist[row * 4 + col])) for row in range(4)) + 16 for col in range(4)]
width = sum(widths) + 5
count = 0
for i in range(16):
    print('|{:^{width}}'.format(colored(nlist[i], 'white', 'on_'+color[nlist[i]]), width=widths[i % 4]), end = '')
    count += 1
    if count == 4:
        print("|\n" + '-' * width)
        count = 0
print("")

Output I do see the following output in colors

|  2  |  4   |  8   |  16  |
------------------------------------------------------------------------------------
| 32  |  64  | 128  | 256  |
------------------------------------------------------------------------------------
| 512 | 1024 | 2048 | 4096 |
------------------------------------------------------------------------------------
| 128 |  2   |  2   |  16  |
------------------------------------------------------------------------------------

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.