Skip to content

@maettig /LICENSE.txt forked from 140bytes/LICENSE.txt
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Pac-Man in 140byt.es

A simple variation of the Pac-Man game (almost) made with 140byt.es snippets.

My setInnerHTML uses tricks learned from @jed's cssSelect. Everything else is created from scratch. Tested with Opera and Firefox. Does not work in Internet Explorer 8.

function(l, k, w) //level, keyCode, level width
{
l[l.x] = ' '; //remove player from level
if (l[l.x + l.d] == '#') //check if previous walking direction is possible
l.d = 0; //stop
if (k > 36 && k < 41 && //check if a cursor key was pressed
l[l.x + (k = k % 2 //calculate walking direction
? k - 38 //-1 is left, +1 is right
: (k - 39) * w //-width is up, +width is down
)] != '#') //check if not walking into a wall
l.d = k; //set new walking direction
l.p += l[l.x += l.d //walk
] == '.'; //and increase points
l[l.x] = 'P' //place player in level
}
function(l,k,w){l[l.x]=' ';if(l[l.x+l.d]=='#')l.d=0;if(k>36&&k<41&&l[l.x+(k=k%2?k-38:(k-39)*w)]!='#')l.d=k;l.p+=l[l.x+=l.d]=='.';l[l.x]='P'}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Thiemo Mättig <http://maettig.com/>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "pacMan",
"description": "Pac-Man made with 140byte.es snippets.",
"keywords": [
"game",
"pacman"
]
}
<!DOCTYPE HTML>
<pre>Loading...</pre>
<span id="points">0</span> points
<style type="text/css">
body { background: #000; color: #FFF; font-family: Consolas, monospace; margin: 4em; text-shadow: 0 0 0.2em #FFF; }
pre { font-size: 4em; line-height: 0.55em; margin: 0; }
.air { color: #222; text-shadow: 0 0 0.2em #222; }
.wall { color: #30F; text-shadow: 0 0 0.2em #30F; }
.player { color: #FF0; text-shadow: 0 0 0.2em #FF0; }
#points { font-size: 2em; line-height: 2em; }
</style>
<script>
// 153 bytes, any idea how to save 13 bytes?
var setInnerHTML = function(a, h)
{
a = /(\W?)(.*)/.exec(a);
(a[1] == '#'
? document.getElementById(a[2])
: document['getElementsBy' + (a[1] ? 'Class' : 'Tag') + 'Name'](a[2])[0]
).innerHTML = h
}
// 97 bytes, maybe use the remaining 43 bytes to make this more flexible?
var parseLevel = function(l, w)
{
l = l.join ? l.join('\n') : l;
w = l.indexOf('\n') + 1;
l = l.split('');
l.w = w;
l.d = l.p = 0;
return l
}
// 99 bytes, should be enough to add a "you won" screen.
var renderLevel = function(l, t)
{
for (var h = '', x = 0; x < l.length; x++)
{
if (l[x] == 'P') l.x = x;
h += t[l[x]] ? t[l[x]] : l[x]
}
return h
}
// 140 bytes
var updateLevel = function(l, k, w)
{
l[l.x] = ' ';
if (l[l.x + l.d] == '#')
l.d = 0;
if (k > 36 && k < 41 && l[l.x + (k = k % 2 ? k - 38 : (k - 39) * w)] != '#')
l.d = k;
l.p += l[l.x += l.d] == '.';
l[l.x] = 'P'
}
var theme = {
' ': '<span class="air">\u2219</span>',
'.': '<span class="gold">\u2219</span>',
'#': '<span class="wall">\u25A1</span>',
'P': '<span class="player">\u263B</span>'
};
var level = parseLevel(
'###################\n' +
'#....#.......#....#\n' +
'#.##.#.#####.#.##.#\n' +
'#.#.............#.#\n' +
'#.#.##.##.##.##.#.#\n' +
'#......#...#......#\n' +
'#.#.##.#####.##.#.#\n' +
'#.#......P......#.#\n' +
'#.##.#.#####.#.##.#\n' +
'#....#.......#....#\n' +
'###################');
window.onkeydown = function(e)
{
level.keyCode = (e || window.event).keyCode;
}
window.setInterval(function()
{
setInnerHTML('PRE', renderLevel(level, theme));
setInnerHTML('#points', level.p);
updateLevel(level, level.keyCode, level.w);
}, 250)
</script>
@jed

here's a demo.

@p01

getFirstElement in 134bytes:

function(a){a=/(\W?)(.*)/.exec(a);return(a=document['getElement'+(a[1]=='#'?'ById':a[1]?'sByClassName':'sByTagName')](a[2]))&&a[0]||a}
@maettig
Owner

It's so easy. Thank you. Enough room to add the possibility to omit the parameter. In this case it returns the first element in the document (which is the HTMLHtmlElement in most browsers but the DOCTYPE as an HTMLCommentElement in IE). This is 139 bytes. I tried to allow the parameter '*' instead or in addition to leaving out the parameter but if I do so it always becomes bigger than 140 bytes.

function(a){a=/(\W?)(.*)/.exec(a||' *');a=document['getElement'+(a[1]>'-'?'sByClassName':a[1]<1?'sByTagName':'ById')](a[2]);return a[0]||a}
@qfox

Some basics...

if(x)y; could be x&&y;
if(x)y;else z; could be x?y:z;

More specific cases:

I think k>36&&k<41 could be k-36<5

So with the above, the ifs first become:

l[l.x+l.d]=='#' && l.d=0; 
k-36<5&&l[l.x+(k=k%2?k-38:(k-39)*l.w)]!='#'&&l.d=k;

I think there are some more "easy" gains to be had but I don't really have the time right now to dive deeper into it...

@maettig
Owner

@qfox, you are right, all if can be replaced with &&. Thank you. Edit: To bad, using && does not save a byte. if(a)b=c; needs to be a&&(b=c);. And k-36<5 = k-36+36<5+36 = k<41 so it's not the same.

@p01, I think I found an almost perfect solution for my getFirstElement function (138 bytes). Now it's possible to use IDs (e.g. '#top'), class names (e.g. '.item'), tag names (e.g. 'pre'), the special class name '*' and no parameter (does the same as '*').

function(a){a=/([#.]?)(.*)/.exec(a||'*');a=document['getElement'+(a[1]>'-'?'sByClassName':a[1]?'ById':'sByTagName')](a[2]);return a[0]||a}
@maettig
Owner

After some bit fiddling I found that k>36&&k<41?true:false is identical to k-37>>2?false:true. I saved some additional bytes by rearranging the code without changing the game logic. I did an update. Next step? Adding enemies? Graphical tiles? A bunch of 140 bytes GIFs? Edit: While looking at what I did I saw it's possible to move l.d=... down to where it's used. 127 bytes.

@maettig
Owner

New features: A ghost is walking around. Internet Explorer is supported. Graphics are supported. Unfortunately, I have no idea how to upload binary files at GitHub so you have to download this ZIP archive to see my bunch of tiny GIF images (each below 140 bytes, of course) in action. Next step: Multiple ghosts.

@tsaniel

The bad thing is that the control is lagged.

@maettig
Owner

You are right. I was always wondering since I started working on this. Now I found the reason. I was doing the main loop in the wrong order: It was waiting for a key → rendering the level → processing the key. Now it is waiting for a key → processing the key → rendering the level.

@maettig
Owner

Major update to my "Pac-Man in @140bytes" adventure: It's a full game now, including multiple levels and ghosts. Click here to play it.

@tsaniel

Great.

@maettig
Owner

I introduced a bug while golfing my updateGhosts function down. Some ghosts in the last level got stuck. Now I'm back at 152 bytes for that function.

@p01

Sorry I haven't tried but why not replace the following code in updateGhosts

for(g=a.length;g--;)
  l[a[g].x]=a[g].b;
for(g in a)
{
  g=a[g];
  //...

by

for(g in a)
{
  g=a[g];
  l[g.x]=g.b;
  //...
@maettig
Owner

When the paths of two ghosts intersect the first stores a backup of the ground (which is either air or gold) and the second stores a backup of the first ghost. I have to restore these backups in reverse order.

I think I can drop this backup stuff. Edit: I did it. I introduced this when my array was made of characters. But I switched to integers. Now a ghost (8) on gold (2) can be stored as 10. Setting a ghost is |8, removing a ghost is &7.

@p01

Nice touch with the bitmask. I replaced:

for(g=a.length;g--;)
  l[a[g].x]&=7;
for(g in a)
{
  g=a[g];
  //...

by

for(g in a)
{
  g=a[g];
  l[g.x]&=7;
  //...

and played a couple of levels without noticing any glitch.

@maettig
Owner

Thanks. There is a tiny glitch unfortunately. If the paths of two ghosts intersect one of the ghosts disappears for one frame.

If your looking for a new challenge, my decodeMinecraftColors needs to be golfed down by 10 bytes.

@aemkei

Wow: that was more than three years ago!

Now we reanimate this awesome work and hacked the HTML+JS down to 460 bytes:

https://github.com/codegolf/pac-man/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.