title: Create a Simon Clone!

text:
# Question
Title: Create a Simon Clone!
**Scenario:** while programming you have a sudden nostalgic urge for the '80s and cheesy games.

**Requirements:** Make a GUI program (text probably won't work) for Simon, the game. Input can be clicking, or pressing a key. You should divide the screen into 4 regions: yellow, blue, red, green. When the game starts, a random color lights up and you activate it. Then, two lights come on, one after the other, and you need to activate those in order, etc. The game ends when you press the wrong color.

**Bonuses:**

-100 if you include sound (a different note played when pressing each region and when the game shows you the colors)

-25 if you include a score counter.

# Answer
> 12 votes
# Bash ~~318~~ ~~297~~ ~~281~~ ~~273~~ ~~268~~ ~~244~~ 240-125=115

This is primarily a response to "Text probably won't work"; the following text-based bash script runs fine in `Konsole`, `gnome-terminal` etc. on my Ubuntu 14.04 machine. To create the regions of colour it sets the text background color. In fact, adding text makes the game more accessible to color-blind players. To make the game yet more accessible it reads the characters that the player needs to press (it assumes that `espeak` is installed). It also assumes that the only file matching `/d*/ur*/` is `/dev/urandom`. For the regions of color to be of non-trivial size you probably want to set the text size to be quite large. Also if you want the regions of color to be quadrants, you have to run it in a terminal that is two characters wide.

To play press y, r, g or b as appropriate.

```
cat <<"EOF"|sed s/E/`echo -e '\E'`/>simon_golf.sh;bash simon_golf.sh;wc simon_golf.sh
d(){ echo Ecx1r09mRx2g10mGx3y11mYx4b14mBx0m$s|sed s/.$1"//
s/[rgyb]..//g
s/x/E[48;5;/g";};x(){ d $c;espeak $c;d j;};l(){
for c in $o;{ eval $1;x;};};f(){ o=$o\ `tr -dc yrgb</d*/ur*|head -c1`
l;l 'read -n1 i;[ $c = $i ]||exit;let s++';f;};f
EOF

```

This solution contains two non-printable ESC characters. Although these ESC character appear in the preview, they seem to get deleted after submission, so the code above is a wrapper that generates and runs the golfed `simon_golf.sh`.

See also the original ungolfed version, and the slightly more playable 256 byte version.

The screenshots below are when the yellow light is on and the player's score is 7. The screenshot on the right has been desaturated to simulate colour-blindness.

# Answer
> 24 votes
## Scratch, 1604 – 125 = 1479

I'm here for the fun, not the golf.

**Edit:** updated scoring method based on community consensus.

Main program:

Individual sprites:

This is the sprite with number `0`. The other sprites have the same script, except the number.

Play with it online.

Code used for byte counting: (Using snippet to hide code)

```
when green flag clicked
set [s v] to [0]
delete (all v) of [a v]
forever
  set [x v] to (pick random (0) to (3))
  add (x) to [a v]
  set [i v] to [1]
  repeat (length of [a v] :: list)
    broadcast (item (i) of [a v] :: list)
    wait (0.3) secs
    change [i v] by (1)
  end
  set [i v] to [1]
  wait until <(x) = [4]>
end

when I receive [0 v]
play sound [0 v]
next costume
wait (0.3) secs
next costume

when this sprite clicked
broadcast [0 v]
wait (0.3) secs
if <[0] = (item (i) of [a v] :: list)> then
  change [i v] by (1)
else
  stop [all v]
end
if <(i) > (length of [a v] :: list)> then
  set [x v] to [4]
  change [s v] by (1)
end

when this sprite clicked
broadcast [3 v]
wait (0.3) secs
if <[3] = (item (i) of [a v] :: list)> then
  change [i v] by (1)
else
  stop [all v]
end
if <(i) > (length of [a v] :: list)> then
  set [x v] to [4]
  change [s v] by (1)
end

when I receive [3 v]
play sound [3 v]
next costume
wait (0.3) secs
next costume

when I receive [1 v]
play sound [1 v]
next costume
wait (0.3) secs
next costume

when this sprite clicked
broadcast [1 v]
wait (0.3) secs
if <[1] = (item (i) of [a v] :: list)> then
  change [i v] by (1)
else
  stop [all v]
end
if <(i) > (length of [a v] :: list)> then
  set [x v] to [4]
  change [s v] by (1)
end

when this sprite clicked
broadcast [2 v]
wait (0.3) secs
if <[2] = (item (i) of [a v] :: list)> then
  change [i v] by (1)
else
  stop [all v]
end
if <(i) > (length of [a v] :: list)> then
  set [x v] to [4]
  change [s v] by (1)
end

when I receive [2 v]
play sound [2 v]
next costume
wait (0.3) secs
next costume
```

Note: Code automatically generated using scratchblocks generator, modified as somehow the generator doesn't correctly handle decimal numbers (treating 0.3 as 0).

Screenshot:

*Note: Please do not press two buttons within 0.3 seconds.*

# Answer
> 3 votes
## Mathematica, 409 - 125 = 284

```
k = 2;
p = Tuples[{0, 1}, 2];
f[c_, p_] :=
 EventHandler[{c, Rectangle[p]},
  "MouseClicked" :> (AppendTo[x, p]; Beep[]; g)]
h[R_] := (i = 1;
  RunScheduledTask[
   H = If[OddQ@i,
     Beep[]; {EdgeForm[{Thickness[0.02], Black}], FaceForm[],
      Rectangle@R[[Ceiling[i/2]]]}, {}]; i++, {.3, 2 Length@R}])
s := (m = 0; x = {}; h[R = RandomChoice[p, k]];)
g := (m++; If[Take[R, m] != x, k = 2; s, If[m == k, k++; s]])
Dynamic@Graphics[{MapThread[f, {{Yellow, Red, Blue, Green}, p}], H},
  PlotLabel -> k]
s

```

# Answer
> 2 votes
## Windows PowerShell (CLI), 272 - 100 - 25 = 147

```
$d={param($c)cls;sleep -m 99;'R','Y','Blu','Gre'|
%{Write-Host '#' -N -F "$(if($i%4-ne $c){'Dark'})$_";
$i++}};$b={param($c)&$d $c;[console]::Beep(($c+1)*99,700);&$d};
$m=@();$s=0;for(){$m+=0..3|Get-Random;$m|%{&$b $_};$m|%{
if((read-host)-ne $_){$s;exit}&$b $_};$s++;sleep 1}

```

I've added newlines here to avoid side-scrolling, but it works as one line so the character count is without newlines.

Screenshot:

To play:

* Open PowerShell ISE (v3), paste script into text editor, press F5 to run.
* Game will light up a color, play a sound, then wait for input
* Press a number (0=red, 1=yellow, 2=blue, 3=green) then Enter.
* If you are wrong it prints the score and quits. (NB. it might exit your console).
* If you are right it goes for two notes.
* You have to press Enter between each note when playing the sequence back.

Comments:

* "divide the screen into 4 regions" - you didn't say they had to be quarters, so they aren't.
* It's hard to see blue light up on the blue background, but it does.
* Please run in PowerShell ISE - in the normal prompt "DarkYellow" shows as white.
* You could arguably golf another 28 characters off by removing some of the timing (still making the game playable), and by interpreting the rule "sound (a note played when pressing and when the game shows you the colors)" to mean "they can all be the same sound - default error DING", but I think that's too far against the spirit of it.

# Answer
> 0 votes
ZXBasic: 422 - 100 - 25 = 297

This definitely counts as a nostalgic urge for the '80s...

ZXBasic uses a combination of FreeBASIC type commands and ZX Spectrum BASIC to allow loops and repeats which then turn into TZX format to load into a Spectrum emulator.

This version changes the border (although a legend on screen says which key to press). It plays the same notes as original Simon game (http://en.wikipedia.org/wiki/Simon\_%28game%29).

```
d=0.5:s=0:l=1:t=1:n$="4261":dim m(4)=>{-8,9,1,4}
border 7
while l>0
 cls:a$="":print at 1,1;"Level: ";t;at 2,1;"Score:";s::for i=1 to 4:print at 0,i;paper val(n$(i));ink 0;i:next
 for i=1 to t
  c=1+int(rnd*4)
  border val(n$(c)):beep d,m(c):border 7
  a$=a$+str(c)
 next
 print at 10,1;"your turn"
 p$="":i=1
 do
  pause 100:k$=inkey:print at 6,i;k$
  if k$=a$(i) then s=s+1:print at 2,7;s:beep d,m(val(k$)):i=i+1
  else l=l-1:i=t+1:print "bad luck!"
  end if
 loop until i>t
 t=t+1:pause 25
end while

```

# Answer
> 0 votes
## HTML5 and Javascript, 1118-100-25=993 bytes

Way too bloated HTML+Js version.

Plays sounds through the Web Audio API.

Frequencies of the notes should be the original Simon's ones, colours and colour placement too.

There is an online demo here: http://www.dantonag.it/miniSimon.html. Works in Web Audio compliant browsers (at least Chrome and Firefox, IE doesn't support it, AFAIK).

```
<html><script>
var hc=["#0f0","red","#ff3","blue"],lc=["#090","#930","#cc0","#33c"],nt=[391,329,261,195],ln=[],qpos=0,pm=0,x,ct=new AudioContext;function ps(a,d){var b=ct.createOscillator();b.frequency.value=d;b.connect(ct.destination);var c=ct.createGain();b.connect(c);c.connect(ct.destination);c.gain.value=-.5;x[a].style.backgroundColor=hc[a];b.start(0);setTimeout(function(a,b){a.stop(0);x[b].style.backgroundColor=lc[b]},500,b,a)}
function w(a){2==pm&&(a!=ln[qpos]?(pm=3,document.getElementsByTagName("span")[0].innerHTML="game over!",ps(a,156)):(qpos++,ps(a,nt[a]),qpos>=ln.length&&(pm=qpos=0)))}function ml(){if(0==pm)document.getElementsByTagName("div")[0].innerHTML=ln.length,ln.push(Math.floor(4*Math.random())),pm=1;else if(1==pm){var a=ln[qpos];qpos<ln.length?(ps(a,nt[a]),qpos++):(qpos=0,pm=2)}setTimeout(ml,500)}window.onload=function(){setTimeout(ml,1);x=document.getElementsByTagName("td")};</script><div>0</div><table cellpadding=40><tr><td bgcolor=#090 onmousedown=w(0)><td bgcolor=#930 onmousedown=w(1)><tr><td bgcolor=#cc0 onmousedown=w(2)><td bgcolor=#33c onmousedown=w(3)></table><span></span>

```

My record is 15 (I'm pretty bad at this game). What's yours?

---
Tags: code-golf, game
---