Create a Simon Clone!

18

2

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.

qwr

Posted 2014-03-29T03:10:22.053

Reputation: 8 929

Question was closed 2018-03-26T14:54:23.777

@Liam McInroy AFAIK a block is 2 bytes for the block ID and 4 bytes to store it's position in the world. – Pavel – 2016-09-26T19:33:14.327

13GUI and code-golf don't generally work together. – user80551 – 2014-03-29T06:40:25.053

3This should be doable in Minecraft. Wouldn't surprise me if someone already has. Don't know how one'd submit that here though... – Kninnug – 2014-03-29T10:58:11.443

@Kninnug the amount of blocks * bytes per block;) – Liam McInroy – 2014-03-29T18:08:05.533

Answers

12

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.

screenshotBlackandWhite

gmatht

Posted 2014-03-29T03:10:22.053

Reputation: 676

Way too big for a code golf... – John Dvorak – 2014-03-29T07:02:58.530

3True. I am here more for the "Programming Puzzles" more than the "Code Golf". – gmatht – 2014-03-29T07:06:05.700

I have slightly golfed it now. – gmatht – 2014-03-29T11:25:40.243

24

Scratch, 1604 – 125 = 1479

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

Edit: updated scoring method based on community consensus.

Main program:

main

Individual sprites:

sprite

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:

screenshot

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

user12205

Posted 2014-03-29T03:10:22.053

Reputation: 8 752

Due to updated community consensus, the above comment concerning the scoring method is invalidated. – user12205 – 2016-09-26T19:14:42.757

Ha, that's cool. A pause after a correct answer would be good, though, or some congratulatory sound. It sounds like my last move is part of the pattern. Also, I would play the sounds more slowly than the input cap, since rhythm and tone matching is how people (myself, at least) play... still, I like it. +1 – krs013 – 2014-03-29T08:56:47.813

1Scratch? Srs? Also, the byte count imo should be the total size of the SB2. – cjfaure – 2014-03-29T11:06:48.367

1@Trimsty Then it would be 126833 bytes (including the wav sound files etc), which is why I said "I'm here for the fun, not the golf." – user12205 – 2014-03-29T11:11:35.593

According to the scoring I suggested here, the score is 60 (27 blocks, 20 chars/digits in constants, 8 operators, 5 variable uses). With bonuses, you get -65.

– ugoren – 2014-03-30T06:34:21.787

@ugoren This is actually only a partial answer. There are 4 sprites, and only the script for one is shown, since the other sprites have almost identical scripts except the number. I will update the answer based on your scoring. Thanks. – user12205 – 2014-03-30T15:53:10.753

@ugoren Hmm... perhaps not. I don't quite get how you counted 8 operators. – user12205 – 2014-03-30T16:06:13.383

@ace, I actually counted funcrions, like item..of as operators. – ugoren – 2014-03-30T16:37:53.417

@ugoren Okay, gotcha. Break-down of the count of 150: Main program: 13 blocks, 10 chars in constants, 4 operators and 3 variables, totalling 30. Each sprite: 14 blocks, 10 char in constants, 4 operators and 2 variables, totalling 30. Total count = 30 * 4 + 30 = 150. – user12205 – 2014-03-30T16:53:45.573

3

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

enter image description here

swish

Posted 2014-03-29T03:10:22.053

Reputation: 7 484

2

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: Screenshot of game playing

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.

TessellatingHeckler

Posted 2014-03-29T03:10:22.053

Reputation: 2 412

0

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

Best score In play

Brian

Posted 2014-03-29T03:10:22.053

Reputation: 1 209

0

HTML5 and Javascript, 1118-100-25=993 bytes

enter image description here

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?

Gabriele D'Antona

Posted 2014-03-29T03:10:22.053

Reputation: 1 336