Black box
Implement a version of the Black Box game beginners configuration: 4 Atoms in an 8 x 8 grid.
Determine where the hidden atoms are in the box, by observing how the light beams fired into the box react when leaving it.
Possible results:
'H': the beam hit an atom and stopped
'R': Either the beam was reflected back the way it came or there was a ball just to one side of its entry point
'Numbers': indicate that the beam entered one of those squares and emerged from the other
Extra credit (Different game types):
-More or less atoms (maybe random)
-Different grid sizes
Go
Terminal based game.
Just the basic configuration - 4 atoms in an 8 x 8 grid.
To test it against known output (as opposed to playing a sensible game), the program has been fixed (wikiGame = true) to reproduce the atom position in the Wikipedia article's example game, followed by a complete set of beams and one incorrect and three correct guesses.
Set wikiGame to false to play a normal 'random' game. <lang go>package main
import (
"bufio" "fmt" "log" "math/rand" "os" "strings" "time"
)
var (
b = make([]rune, 100) // displayed board h = make([]rune, 100) // hidden atoms scanner = bufio.NewScanner(os.Stdin) wikiGame = true // set to false for a 'random' game
)
func initialize() {
for i := 0; i < 100; i++ { b[i] = ' ' h[i] = 'F' } if !wikiGame { hideAtoms() } else { h[32] = 'T' h[37] = 'T' h[64] = 'T' h[87] = 'T' } fmt.Println(` === BLACK BOX ===
H Hit (scores 1) R Reflection (scores 1) 1-9, Detour (scores 2) a-c Detour for 10-12 (scores 2) G Guess (maximum 4) Y Correct guess N Incorrect guess (scores 5) A Unguessed atom Cells are numbered a0 to j9. Corner cells do nothing. Use edge cells to fire beam. Use middle cells to add/delete a guess. Game ends automatically after 4 guesses. Enter q to abort game at any time. `)
}
func drawGrid(score, guesses int) {
fmt.Printf(" 0 1 2 3 4 5 6 7 8 9 \n") fmt.Printf("\n") fmt.Printf(" ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗\n") fmt.Printf("a %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9]) fmt.Printf(" ╔═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╗\n") fmt.Printf("b ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("d ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[30], b[31], b[32], b[33], b[34], b[35], b[36], b[37], b[38], b[39]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("e ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[40], b[41], b[42], b[43], b[44], b[45], b[46], b[47], b[48], b[49]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("f ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[50], b[51], b[52], b[53], b[54], b[55], b[56], b[57], b[58], b[59]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("g ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[60], b[61], b[62], b[63], b[64], b[65], b[66], b[67], b[68], b[69]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("h ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[70], b[71], b[72], b[73], b[74], b[75], b[76], b[77], b[78], b[79]) fmt.Printf(" ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣\n") fmt.Printf("i ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║\n", b[80], b[81], b[82], b[83], b[84], b[85], b[86], b[87], b[88], b[89]) fmt.Printf(" ╚═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╝\n") fmt.Printf("j %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c ║ %c\n", b[90], b[91], b[92], b[93], b[94], b[95], b[96], b[97], b[98], b[99]) fmt.Printf(" ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝\n") status := "In play" if guesses == 4 { status = "Game over!" } fmt.Println("\n Score =", score, "\tGuesses =", guesses, "\t Status =", status, "\n")
}
func hideAtoms() {
placed := 0 for placed < 4 { a := 11 + rand.Intn(78) // 11 to 88 inclusive m := a % 10 if m == 0 || m == 9 || h[a] == 'T' { continue } h[a] = 'T' placed++ }
}
func nextCell() int {
var ix int for { fmt.Print(" Choose cell : ") scanner.Scan() sq := strings.ToLower(scanner.Text()) if len(sq) == 1 && sq[0] == 'q' { log.Fatal("program aborted") } if len(sq) != 2 || sq[0] < 'a' || sq[0] > 'j' || sq[1] < '0' || sq[1] > '9' { continue } ix = int((sq[0]-'a')*10 + sq[1] - 48) if atCorner(ix) { continue } break } check(scanner.Err()) fmt.Println() return ix
}
func atCorner(ix int) bool { return ix == 0 || ix == 9 || ix == 90 || ix == 99 }
func inRange(ix int) bool { return ix >= 1 && ix <= 98 && ix != 9 && ix != 90 }
func atTop(ix int) bool { return ix >= 1 && ix <= 8 }
func atBottom(ix int) bool { return ix >= 91 && ix <= 98 }
func atLeft(ix int) bool { return inRange(ix) && ix%10 == 0 }
func atRight(ix int) bool { return inRange(ix) && ix%10 == 9 }
func inMiddle(ix int) bool {
return inRange(ix) && !atTop(ix) && !atBottom(ix) && !atLeft(ix) && !atRight(ix)
}
func play() {
score, guesses := 0, 0 num := '0'
outer:
for { drawGrid(score, guesses) ix := nextCell() if !inMiddle(ix) && b[ix] != ' ' { // already processed continue } var inc, def int switch { case atTop(ix): inc, def = 10, 1 case atBottom(ix): inc, def = -10, 1 case atLeft(ix): inc, def = 1, 10 case atRight(ix): inc, def = -1, 10 default: if b[ix] != 'G' { b[ix] = 'G' guesses++ if guesses == 4 { break outer } } else { b[ix] = ' ' guesses-- } continue } var x int first := true for x = ix + inc; inMiddle(x); x += inc { if h[x] == 'T' { // hit b[ix] = 'H' score++ first = false continue outer } if first && (inMiddle(x+def) && h[x+def] == 'T') || (inMiddle(x-def) && h[x-def] == 'T') { // reflection b[ix] = 'R' score++ first = false continue outer } first = false y := x + inc - def if inMiddle(y) && h[y] == 'T' { // deflection switch inc { case 1, -1: inc, def = 10, 1 case 10, -10: inc, def = 1, 10 } } y = x + inc + def if inMiddle(y) && h[y] == 'T' { // deflection or double deflection switch inc { case 1, -1: inc, def = -10, 1 case 10, -10: inc, def = -1, 10 } } } if num != '9' { num++ } else { num = 'a' } if b[ix] == ' ' { score++ } b[ix] = num if inRange(x) { if ix == x { b[ix] = 'R' } else { if b[x] == ' ' { score++ } b[x] = num } } } drawGrid(score, guesses) finalScore(score, guesses)
}
func check(err error) {
if err != nil { log.Fatal(err) }
}
func finalScore(score, guesses int) {
for i := 11; i <= 88; i++ { m := i % 10 if m == 0 || m == 9 { continue } if b[i] == 'G' && h[i] == 'T' { b[i] = 'Y' } else if b[i] == 'G' && h[i] == 'F' { b[i] = 'N' score += 5 } else if b[i] == ' ' && h[i] == 'T' { b[i] = 'A' } } drawGrid(score, guesses)
}
func main() {
rand.Seed(time.Now().UnixNano()) for { initialize() play() inner: for { fmt.Print(" Play again y/n : ") scanner.Scan() yn := strings.ToLower(scanner.Text()) switch yn { case "n": return case "y": break inner } } check(scanner.Err()) }
}</lang>
- Output:
As the grid is displayed 29 times in all, this has been abbreviated to show just the first 2 and the last 3.
=== BLACK BOX === H Hit (scores 1) R Reflection (scores 1) 1-9, Detour (scores 2) a-c Detour for 10-12 (scores 2) G Guess (maximum 4) Y Correct guess N Incorrect guess (scores 5) A Unguessed atom Cells are numbered a0 to j9. Corner cells do nothing. Use edge cells to fire beam. Use middle cells to add/delete a guess. Game ends automatically after 4 guesses. Enter q to abort game at any time. 0 1 2 3 4 5 6 7 8 9 ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ a ║ ║ ║ ║ ║ ║ ║ ║ ║ ╔═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╗ b ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ c ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ d ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ e ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ f ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ g ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ h ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ i ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╝ j ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ Score = 0 Guesses = 0 Status = In play Choose cell : b0 0 1 2 3 4 5 6 7 8 9 ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ a ║ ║ ║ ║ ║ ║ ║ ║ ║ ╔═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╗ b ║ 1 ║ ║ ║ ║ ║ ║ ║ ║ ║ 1 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ c ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ d ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ e ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ f ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ g ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ h ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ i ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╝ j ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ Score = 2 Guesses = 0 Status = In play Choose cell : c0 ................ (Screens 3 to 26 omitted) ................ Score = 32 Guesses = 2 Status = In play Choose cell : g4 0 1 2 3 4 5 6 7 8 9 ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ a ║ 2 ║ H ║ 9 ║ H ║ 7 ║ 9 ║ H ║ 8 ║ ╔═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╗ b ║ 1 ║ ║ ║ ║ ║ ║ ║ ║ ║ 1 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ c ║ 2 ║ ║ ║ ║ ║ ║ ║ ║ ║ 8 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ d ║ H ║ G ║ ║ ║ ║ ║ ║ G ║ ║ H ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ e ║ 3 ║ ║ ║ ║ ║ ║ ║ ║ ║ 6 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ f ║ 4 ║ ║ ║ ║ ║ ║ ║ ║ ║ 7 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ g ║ H ║ ║ ║ ║ G ║ ║ ║ ║ ║ H ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ h ║ 5 ║ ║ ║ ║ ║ ║ ║ ║ ║ 6 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ i ║ H ║ ║ ║ ║ ║ ║ ║ ║ ║ H ║ ╚═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╝ j ║ 3 ║ H ║ 5 ║ H ║ 4 ║ R ║ H ║ R ║ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ Score = 32 Guesses = 3 Status = In play Choose cell : i7 0 1 2 3 4 5 6 7 8 9 ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ a ║ 2 ║ H ║ 9 ║ H ║ 7 ║ 9 ║ H ║ 8 ║ ╔═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╗ b ║ 1 ║ ║ ║ ║ ║ ║ ║ ║ ║ 1 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ c ║ 2 ║ ║ ║ ║ ║ ║ ║ ║ ║ 8 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ d ║ H ║ G ║ ║ ║ ║ ║ ║ G ║ ║ H ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ e ║ 3 ║ ║ ║ ║ ║ ║ ║ ║ ║ 6 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ f ║ 4 ║ ║ ║ ║ ║ ║ ║ ║ ║ 7 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ g ║ H ║ ║ ║ ║ G ║ ║ ║ ║ ║ H ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ h ║ 5 ║ ║ ║ ║ ║ ║ ║ ║ ║ 6 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ i ║ H ║ ║ ║ ║ ║ ║ ║ G ║ ║ H ║ ╚═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╝ j ║ 3 ║ H ║ 5 ║ H ║ 4 ║ R ║ H ║ R ║ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ Score = 32 Guesses = 4 Status = Game over! 0 1 2 3 4 5 6 7 8 9 ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ a ║ 2 ║ H ║ 9 ║ H ║ 7 ║ 9 ║ H ║ 8 ║ ╔═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╗ b ║ 1 ║ ║ ║ ║ ║ ║ ║ ║ ║ 1 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ c ║ 2 ║ ║ ║ ║ ║ ║ ║ ║ ║ 8 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ d ║ H ║ N ║ A ║ ║ ║ ║ ║ Y ║ ║ H ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ e ║ 3 ║ ║ ║ ║ ║ ║ ║ ║ ║ 6 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ f ║ 4 ║ ║ ║ ║ ║ ║ ║ ║ ║ 7 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ g ║ H ║ ║ ║ ║ Y ║ ║ ║ ║ ║ H ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ h ║ 5 ║ ║ ║ ║ ║ ║ ║ ║ ║ 6 ║ ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ i ║ H ║ ║ ║ ║ ║ ║ ║ Y ║ ║ H ║ ╚═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╝ j ║ 3 ║ H ║ 5 ║ H ║ 4 ║ R ║ H ║ R ║ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ Score = 37 Guesses = 4 Status = Game over! Play again y/n : n
JavaScript
Play it here. <lang javascript> var sel, again, check, score, done, atoms, guesses, beamCnt, brdSize;
function updateScore( s ) {
score += s || 0; para.innerHTML = "Score: " + score;
} function checkIt() {
check.className = "hide"; again.className = "again"; done = true; var b, id; for( var j = 0; j < brdSize; j++ ) { for( var i = 0; i < brdSize; i++ ) { if( board[i][j].H ) { b = document.getElementById( "atom" + ( i + j * brdSize ) ); b.innerHTML = "⚈"; if( board[i][j].T ) { b.style.color = "#0a2"; } else { b.style.color = "#f00"; updateScore( 5 ); } } } }
} function isValid( n ) {
return n > -1 && n < brdSize;
} function stepBeam( sx, sy, dx, dy ) {
var s = brdSize - 2 if( dx ) { if( board[sx][sy].H ) return {r:"H", x:sx, y:sy}; if( ( (sx == 1 && dx == 1) || (sx == s && dx == -1) ) && ( ( sy > 0 && board[sx][sy - 1].H ) || ( sy < s && board[sx][sy + 1].H ) ) ) return {r:"R", x:sx, y:sy}; if( isValid( sx + dx ) ) { if( isValid( sy - 1 ) && board[sx + dx][sy - 1].H ) { dx = 0; dy = 1; } if( isValid( sy + 1 ) && board[sx + dx][sy + 1].H ) { dx = 0; dy = -1; } sx += dx; return stepBeam( sx, sy, dx, dy ); } else { return {r:"O", x:sx, y:sy}; } } else { if( board[sx][sy].H ) return {r:"H", x:sx, y:sy}; if( ( (sy == 1 && dy == 1) || (sy == s && dy == -1) ) && ( ( sx > 0 && board[sx - 1][sy].H ) || ( sx < s && board[sx + 1][sy].H ) ) ) return {r:"R", x:sx, y:sy}; if( isValid( sy + dy ) ) { if( isValid( sx - 1 ) && board[sx - 1][sy + dy].H ) { dy = 0; dx = 1; } if( isValid( sx + 1 ) && board[sx + 1][sy + dy].H ) { dy = 0; dx = -1; } sy += dy; return stepBeam( sx, sy, dx, dy ); } else { return {r:"O", x:sx, y:sy}; } }
} function fireBeam( btn ) {
var sx = btn.i, sy = btn.j, dx = 0, dy = 0;
if( sx == 0 || sx == brdSize - 1 ) dx = sx == 0 ? 1 : - 1; else if( sy == 0 || sy == brdSize - 1 ) dy = sy == 0 ? 1 : - 1; var s = stepBeam( sx + dx, sy + dy, dx, dy ); switch( s.r ) { case "H": btn.innerHTML = "H"; updateScore( 1 ); break; case "R": btn.innerHTML = "R"; updateScore( 1 ); break; case "O": if( s.x == sx && s.y == sy ) { btn.innerHTML = "R"; updateScore( 1 ); } else { var b = document.getElementById( "fire" + ( s.x + s.y * brdSize ) ); btn.innerHTML = "" + beamCnt; b.innerHTML = "" + beamCnt; beamCnt++; updateScore( 2 ); } }
} function setAtom( btn ) {
if( done ) return; var b = document.getElementById( "atom" + ( btn.i + btn.j * brdSize ) ); if( board[btn.i][btn.j].T == 0 && guesses < atoms ) { board[btn.i][btn.j].T = 1; guesses++; b.innerHTML = "⚈"; } else if( board[btn.i][btn.j].T == 1 && guesses > 0 ) { board[btn.i][btn.j].T = 0; guesses--; b.innerHTML = " "; } if( guesses == atoms ) check.className = "check"; else check.className = "hide";
} function startGame() {
score = 0; updateScore(); check.className = again.className = "hide"; var e = document.getElementById( "mid" ); if( e.firstChild ) e.removeChild( e.firstChild ); brdSize = sel.value; done = false;
if( brdSize < 5 ) return;
var brd = document.createElement( "div" ); brd.id = "board"; brd.style.height = brd.style.width = 5.2 * brdSize + "vh" e.appendChild( brd ); var b, c, d; for( var j = 0; j < brdSize; j++ ) { for( var i = 0; i < brdSize; i++ ) { b = document.createElement( "button" ); b.i = i; b.j = j; if( j == 0 && i == 0 || j == 0 && i == brdSize - 1 || j == brdSize - 1 && i == 0 || j == brdSize - 1 && i == brdSize - 1 ) { b.className = "corner"; } else { if( j == 0 || j == brdSize - 1 || i == 0 || i == brdSize - 1 ) { b.className = "fire"; b.id = "fire" + ( i + j * brdSize ); } else { b.className = "atom"; b.id = "atom" + ( i + j * brdSize ); } b.addEventListener( "click", function( e ) { if( e.target.className == "fire" && e.target.innerHTML == " " ) fireBeam( e.target ); else if( e.target.className == "atom" ) setAtom( e.target ); }, false ); } b.appendChild( document.createTextNode( " " ) ); brd.appendChild( b ); } }
board = new Array( brdSize ); for( var j = 0; j < brdSize; j++ ) { board[j] = new Array( brdSize ); for( i = 0; i < brdSize; i++ ) { board[j][i] = {H: 0, T: 0}; } }
guesses = 0; beamCnt = 1; atoms = brdSize == 7 ? 3 : brdSize == 10 ? 4 : 4 + Math.floor( Math.random() * 5 );
var s = brdSize - 2, i, j; for( var k = 0; k < atoms; k++ ) { while( true ) { i = 1 + Math.floor( Math.random() * s ); j = 1 + Math.floor( Math.random() * s ); if( board[i][j].H == 0 ) break; } board[i][j].H = 1; }
} function init() {
sel = document.createElement( "select"); sel.options.add( new Option( "5 x 5 [3 atoms]", 7 ) ); sel.options.add( new Option( "8 x 8 [4 atoms]", 10 ) ); sel.options.add( new Option( "10 x 10 [4 - 8 atoms]", 12 ) ); sel.addEventListener( "change", startGame, false ); document.getElementById( "top" ).appendChild( sel ); check = document.createElement( "button" ); check.appendChild( document.createTextNode( "Check it!" ) ); check.className = "hide"; check.addEventListener( "click", checkIt, false ); again = document.createElement( "button" ); again.appendChild( document.createTextNode( "Again" ) ); again.className = "hide"; again.addEventListener( "click", startGame, false ); para = document.createElement( "p" ); para.className = "txt"; var d = document.getElementById( "bot" ); d.appendChild( para ); d.appendChild( check ); d.appendChild( again ); startGame();
} </lang>