6
\$\begingroup\$

Challenge

Display Inky the ghost from Pac-Man using only ANSI escape codes.

fix_inky

Here's a text representation of the image

B B B B B C C C C B B B B B
B B B C C C C C C C C B B B
B B C C C C C C C C C C B B
B C W W C C C C W W C C C B
B W W W W C C W W W W C C B
B E E W W C C E E W W C C B
C E E W W C C E E W W C C C
C C W W C C C C W W C C C C
C C C C C C C C C C C C C C
C C C C C C C C C C C C C C
C C C C C C C C C C C C C C
C C B C C C B B C C C B C C
C B B B C C B B C C B B B C
Code ANSI Escape Code Background Color
B "\x1b[40m" Black
C "\x1b[46m" Cyan
W "\x1b[47m" White
E "\x1b[44m" Blue

ANSI Intro

This C example shows the use of ANSI escape codes to print example

Disclaimer

No Inky's were harmed in the making of this challenge. inky_note

\$\endgroup\$
8
  • \$\begingroup\$ Suggest an image in text to copy \$\endgroup\$
    – l4m2
    Jan 6 at 0:10
  • \$\begingroup\$ Welcome to the site. This site is for recreational programming competition. This question is not yet sufficiently well defined to form a competition. You've added an objective scoring criterion (as mentioned in the box at top right) but the challenge needs more clarity. Are you looking specifically for the ANSI output, or would any code that produces the image suffice? If it has to be the ANSI output, it would be best to give the exact required output in the question. Also, there's no reason to restrict the challenge to C (we do have tips questions, but not for a task as specific as this) \$\endgroup\$ Jan 6 at 10:56
  • 1
    \$\begingroup\$ @LevelRiverSt If you read the bottom, the challenge is not restricted to C, and I think it's clear from the title that OP is asking for the image to be drawn in ANSI escape codes, although you could argue that it still needs clarity there. \$\endgroup\$
    – noodle man
    Jan 6 at 14:40
  • \$\begingroup\$ May we output extra black lines at the top and/or the bottom of the ghost? \$\endgroup\$
    – Arnauld
    Jan 6 at 17:27
  • 2
    \$\begingroup\$ It would be interesting to see inky displayed on a Commodore 64 (using PETSCII) or emulator. If it works, I see why no reason to restrict inky to just ANSI. \$\endgroup\$
    – vengy
    Jan 7 at 0:37

7 Answers 7

5
\$\begingroup\$

JavaScript (ES6), 146 bytes

NB: The actual code contains the unprintable character \x1b.

f=(x=n=0)=>n<195?(x>13?`
`:`\x1b[4${"6074"[[5301,4781,4097,p=2731,p,2861,130,,,,,748,2458][y=n/15|0]*3>>x&1|7800/"52225"[y-3]>>x&2]}m `)+f(++n%15):""

Try it online!

Or 148 bytes to restore a black background.

Output

Inky

Encoding

y black/blue layer decimal / 3 white/blue layer decimal
0 11111000011111 15903 5301 00000000000000 0
1 11100000000111 14343 4781 00000000000000 0
2 11000000000011 12291 4097 00000000000000 0
3 10000000000001 8193 2731 00001100001100 780
4 10000000000001 8193 2731 00011110011110 1950
5 10000110000111 8583 2861 00011110011110 1950
6 00000110000110 390 130 00011110011110 1950
7 00000000000000 0 0 00001100001100 780
8 00000000000000 0 0 00000000000000 0
9 00000000000000 0 0 00000000000000 0
10 00000000000000 0 0 00000000000000 0
11 00100011000100 2244 748 00000000000000 0
12 01110011001110 7374 2458 00000000000000 0
\$\endgroup\$
4
  • \$\begingroup\$ Pretty, nice work! I wonder instead of using a single character for each rectangular block, maybe make it double the width using two characters so they're more square looking. Just a thought. \$\endgroup\$
    – vengy
    Jan 6 at 18:05
  • 6
    \$\begingroup\$ This is code-golf. Nobody is going to do that if it costs an extra byte, unless this is a strict requirement. ;-) \$\endgroup\$
    – Arnauld
    Jan 6 at 18:10
  • \$\begingroup\$ True. I just tried double spacing myself and the overall size went from 809 to 812, so single character width is fine. Thanks. \$\endgroup\$
    – vengy
    Jan 6 at 18:24
  • 1
    \$\begingroup\$ It is not a DOS terminal, it is Command Prompt. \$\endgroup\$
    – Joao-3
    Jan 6 at 20:54
2
\$\begingroup\$

Commodore C64, using PETSCII graphics, ~392 BASIC bytes

The simplest way to do this is to use the reverse character mode to print out white spaces, but changing the colours as necessary. These are Control characters in Commodore BASIC, similar to escaped characters in a C or PHP string. We will use a string array B$, and then a FOR/NEXT loop to output to the C64 screen. All colours in this listing are accessed by the control (often referred to as CTRL) key, by pressing the following key combinations:

{BLACK} is CTRL + 1
{WHITE} is CRTL + 2
{CYAN} is CTRL + 4
{BLUE} is CRTL + 7
{REVERSE ON} is CTRL + 9

To make the listing clearer and easier to type in, {SPACE x 5} indicates 5 spaces following the control character, as looking at the listing in Commodore BASIC might not be very clear.

Here is the listing:

0DIMB$(12):B$(.)="{BLACK}{SPACE x 5}{CYAN}{SPACE x 4}{BLACK}{SPACE x 5}":B$(1)="{BLACK}{SPACE x 3}{CYAN}{SPACE x 8}{BLACK}{SPACE x 3}"
1B$(2)="{BLACK}{SPACE x 2}{CYAN}{SPACE x 10}{BLACK}{SPACE x 2}":B$(3)="{BLACK}{SPACE}{CYAN}{SPACE}{WHITE}{SPACE x 2}{CYAN}{SPACE x 4}{WHITE}{SPACE x 2}{CYAN}{SPACE x 3}{BLACK}{SPACE}"
2B$(4)="{BLACK}{SPACE}{WHITE}{SPACE x 4}{CYAN}{SPACE x 2}{WHITE}{SPACE x 4}{CYAN}{SPACE x 2}{BLACK}{SPACE}":B$(5)="{BLACK}{SPACE}{BLUE}{SPACE x 2}{WHITE}{SPACE x 2}{CYAN}{SPACE x 2}{BLUE}{SPACE x 2}{WHITE}{SPACE x 2}{CYAN}{SPACE x 2}{BLACK}{SPACE}"
3B$(6)="{CYAN}{SPACE}{BLUE}{SPACE x 2}{WHITE}{SPACE x 2}{CYAN}{SPACE x 2}{BLUE}{SPACE x 2}{WHITE}{SPACE x 2}{CYAN}{SPACE x 3}":B$(7)="{CYAN}{SPACE x 2}{WHITE}{SPACE x 2}{CYAN}{SPACE x 4}{WHITE}{SPACE x 2}{CYAN}{SPACE x 4}"
4B$(8)="{CYAN}{SPACE x 14}":B$(9}=B$(8):B$(10)=B$(8):B$(11)="{CYAN}{SPACE x 2}{BLACK}{SPACE}{CYAN}{SPACE x 3}{BLACK}{SPACE x 2}{CYAN}{SPACE x 3}{BLACK}{SPACE}{CYAN}{SPACE x 2}"
5B$(12)="{CYAN}{SPACE}{BLACK}{SPACE x 3}{CYAN}{SPACE x 2}{BLACK}{SPACE x 2}{CYAN}{SPACE x 2}{BLACK}{SPACE x 3}{CYAN}{SPACE}":FORI=.TO12:PRINT"{REVERSE ON}"B$(I):NEXT

Some notes: be careful when entering line 4 as it is 80 characters in length (the maximum number of characters in a logical C64 line). Cursor up so that the flashing cursor is over one of the characters on the line and press the return key. Or, enter this into a Commodore C128, which allows for 160 characters in a logical line; this will work in C64 or C128 mode. I typed this in again from the listing above to check that the number of spaces and control characters are correct, and it seems fine. Best viewed with POKE 53280, 0: POKE 53281, 0: RUN.

By using C128 BASIC, and with the 160 PETSCII character per logical line, this can be crunched further as you will be able to reduce the line numbers. Some bytes could also be saved by removing some of the control characters, for instance, where B$(0) ends with {BLACK} there is no need to start B$(1) with {BLACK}. I will try to crunch this further to save some more bytes.

And here is how things look on a C64 (at least a C64 emulator):

Commodore C64 PAC-Man Ghost "Inky"

Commodore C64 PETSCII PAC-Man Ghost "Inky" BASIC listing

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Wow! Awesome to see inky on a C64 emulator using PETSCII. Thanks. \$\endgroup\$
    – vengy
    Jan 7 at 18:17
2
\$\begingroup\$

C (gcc), 151 bytes

-3 thanks to @vengy
-28 thanks to @ceilingcat

Essentially a port of my JS answer.

n;y;main(x){for(;n<195;printf(x>13?"\n":"[4%cm ","6074"[L"㸟㠇〃  ↇƆ\0\0\0\0ࣄ᳎"[y=n++/15]>>x&1|(y>2&y<8)*7800/(~y&3?2:5)>>x&2]))x=n%15;}

Try it online!

Output

Inky

\$\endgroup\$
0
2
\$\begingroup\$

C (gcc), 147 bytes

i=182;main(){for(;i--;)printf("\e[4%cm %s","0674"[3&"ATPATQETQUUUUUUUUUUUUUUUeVeVUzWzGe~e~PiZiJTiUiATUUE@TUU@@PU"[i/3]>>i%3*2],i%14?"":"\e[0m\n");}

Try it online!

-4B from ceilingcat

Port like

Assumes that after ...TUU@@PU there are 2 null bytes

\$\endgroup\$
2
  • \$\begingroup\$ Could shave off another 6 bytes by replacing \x1b with the unprintable ESC character. \$\endgroup\$
    – vengy
    Jan 7 at 3:23
  • 1
    \$\begingroup\$ @vengy Like I said in JavaScript answer, if U+001B is used then the string also can be 4 char per byte \$\endgroup\$
    – l4m2
    Jan 7 at 3:37
2
\$\begingroup\$

Perl 5 + -p0513, 132 bytes

s!!5.2B8.4B5.5B3.CLBCLB2.2MB2MB2.,MB,MB.@/L@/L2BM2BM24B.B<.B<B<2.B2.B3..!;s/\d+(.)/$1x$&/ge;s/./ord$&/ge;s/.{14}\K/
/g;s/./.[4$&m /g

Try it online!

Explanation

The string of random numbers and symbols is an RLE string that contains the data for all the background colours (only the last digit, as the first digit's always 4), this is stored in $_ via the s///ubstitution operator. This is decoded to repeated runs of characters and each of those characters is replaced with its ordinal value, split into run of 14 characters and has the ANSI escape code string wrapped around each value.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 150 bytes

f=(x=182)=>x?`\x1B[4${'0674'[3&Buffer('ATPATQETQUUUUUUUUUUUUUUUeVeVUzWzGe~e~PiZiJTiUiATUUE@TUU@@PU')[--x/3|0]>>x%3*2]}m `+(x%14?'':`\x1b[0m
`)+f(x):''

Try it online!

Hardcode

Arnauld's solution spill color and mine don't. Removing this difference mine is shorter, but Arnauld usen't Buffer

I don't use char \x1B since otherwise it's better encode 4 pos in a char

\$\endgroup\$
1
  • \$\begingroup\$ Tested on linux and Inky looks good. Thanks. \$\endgroup\$
    – vengy
    Jan 7 at 2:57
1
\$\begingroup\$

C (gcc, msvc), 228 bytes

#include<stdio.h>
j,i[]={89391445,88080405,83886085,77597185,111684225,132660865,65552000,10488320,0,0,0,4214800,22040660};main(){for(;j<182;j++)printf("\x1B[4%cm%s","6074"[(i[j/14]>>(2*(13-j%14)))&3],j%14==13?" \x1b[0m\n":" ");}

NB: The actual code contains the unprintable ESC character \x1b.

Try it online!

Output

Windows Command Prompt:

c_inky

Linux (Ubuntu) Terminal:

l_inky

\$\endgroup\$
1

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.