; Incomplete Hangman.jlogo (Lesson 16 - Word and Sentence Iteration)

; Global Variables
; ----------------

; true when the player has won or lost
; false when game is in progress
global "gameOver

; number of wrong characters player has tried
global "badGuessCount

; word of all characters player has guessed
global "guessedChars

; the solution, the target word
global "secretWord

; list of possible secret words
global "possibleSecretWords
make "possibleSecretWords [wordOne wordTwo wordThree wordFour]


; Symbolic Constants
; ------------------
to black
  output 0
  end 
to blue
  output 1
  end
to brown
  output 8
  end
to forest
  output 10
  end
to orange
  output 14
  end
to violet
  output 13
  end
to red
  output 4
  end
to salmon
  output 12
  end
to white
  output 7
  end

to north
  output 0
  end
to east
  output 90
  end

to sansSerif
  output 4
  end


; Graphics Depicting Progress of Guessing
; in this case, bad guesses
; ---------------------------------------

to gallowsBaseY
  output -80
  end
to gallowsLeftX
  output -90
  end
to gallowsHeight
  output 220
  end
to gallowsWidth
  output 130
  end
to ropeLen
  output 20
  end

to drawGallows
  setpencolor black setpensize 8
  penup setxy gallowsLeftX gallowsBaseY pendown
  setheading north forward gallowsHeight
  right 90 forward gallowsWidth
  right 90 setpensize 2 forward ropeLen
  end

to armLen
  output 50
  end
to headRadius
  output 25
  end
to headCenterY
  output difference (sum gallowsBaseY gallowsHeight) (sum ropeLen headRadius)
  end
to neckLen
  output 10
  end
to bodyTopY
  output difference headCenterY (sum headRadius neckLen)
  end
to bodyX
  output sum gallowsLeftX gallowsWidth
  end
to bodyLen
  output 70
  end
to legLen
  output 60
  end

to drawArm1
  penup setxy bodyX bodyTopY pendown
  setpensize 8 setpencolor salmon setheading 130
  forward armLen
  end

to drawArm2
  penup setxy bodyX bodyTopY pendown
  setpensize 8 setpencolor salmon setheading 230
  forward armLen
  end

to drawBody
  penup setxy bodyX bodyTopY pendown
  setpensize 16 setpencolor brown setheading north
  forward neckLen back neckLen
  back bodyLen
  end

to drawHead
  penup setxy bodyX headCenterY
  setpensize 6 setpencolor orange
  repeat 60 [forward (difference headRadius 3) ~
             pendown forward 6 ~
             penup back (sum headRadius 3) ~
             right 6]
  end

to drawLeg1
  penup setxy bodyX (difference bodyTopY bodyLen) pendown
  setpensize 8 setpencolor forest setheading 220
  forward legLen
  end

to drawLeg2
  penup setxy bodyX (difference bodyTopY bodyLen) pendown
  setpensize 8 setpencolor forest setheading 140
  forward legLen
  end

; wrap-up - game over, player lost
to drawYouLose
  penup
  setpencolor red setlabelheight 50
  setxy (sum gallowsLeftX 10)  30 label "You
  setxy (sum gallowsLeftX 10) -30 label "Lose
  setpencolor black setlabelheight 20
  setxy (sum gallowsLeftX 20) -100 label :secretWord
  end

to badGuess
  ;... to be supplied ...
  end


; Graphics Depicting Progress of Guessing
; in this case, correct character guess
; ---------------------------------------
to guessCharSlotWidth
  output 20
  end
to guessCharGap
  output 5
  end

to guessWordY
  output -130
  end

; the width of the space needed to draw the guess word
; depends on the number of characters in the secret word
to guessWordWidth
  localmake "numChar count :secretWord
  output sum (product guessCharSlotWidth :numChar) (product guessCharGap (difference :numChar 1))
  end

to half :num
  output  quotient :num  2
  end

; the guess word is centered on the graphics canvas
; so, half of it is west of 0 on X axis and half of it is east
; output X coordinate for left side of leftmost character of guess word
to guessWordLeftX
  output minus (half guessWordWidth)
  end

; output the X coordinate for the :chNum character of the guess word
; :chNum is 1 for first character, 2 for second character, etc...
to guessCharX :chNum
  output sum guessWordLeftX (product (difference :chNum 1) (sum guessCharSlotWidth guessCharGap))
  end

; draw underscores for character slots of the guess word
to drawEmptyGuessWord :num
  penup setxy guessWordLeftX guessWordY
  setheading east setpensize 2
  repeat :num [pendown forward guessCharSlotWidth penup forward guessCharGap]
  end

; iterate through characters in :wd (which is initially :secretWord)
; and draw :ch in guess word slots where it belongs
; :chIdx starts off at 1 and is incremented on each iteration
to drawCharMatchesHelper :chIdx :wd :ch
  ;... to be supplied ...
  end

; fill in character slots of guess word given a good guess (in :ch)
; so, where :ch matches a character in :secretWord, the
; corresponding character slot in the guess word is filled in
to drawCharMatches :ch
  drawCharMatchesHelper 1 :secretWord :ch
  end

; wrap-up - game over, player won
to drawYouWin
  penup
  setpencolor blue setlabelheight 50
  setxy (sum gallowsLeftX 10)  30 label "You
  setxy (sum gallowsLeftX 10) -30 label "Win!
  end

; output the intersection of :wd and :guessedChars
; recursively iterate through :wd forming new word of all
; characters in :wd that are also in :guessedChars
; :wd is initially :secretWord
to makeGuessWordHelper :wd
  ;... to be supplied ...
  output "
  end

; output the intersection of :secretWord and :guessedChars
; if every character of :secretWord is in :guessedChars,
; the output is :secretWord, else it is a subset of it
to makeGuessWord
  output makeGuessWordHelper :secretWord
  end

; :ch is known to be in :secretWord
; update the guess word in the graphics canvas, and
; check to if player won and if so, wrap up
to goodGuess :ch
  drawCharMatches :ch
  if equal? makeGuessWord :secretWord [drawYouWin make "gameOver "true]
  end

; User Interface Input - keyPressed Event
; if a game is not in progress, ignore the event, otherwise
; keep track of the new guessed character and
; update status of the game based on it
to keyPressed :asciiNum
  if :gameOver [stop]
  localmake "ch (char :asciiNum)
  make "guessedChars word :guessedChars :ch
  ifelse member? :ch :secretWord [goodGuess :ch] [badGuess]
  end

; choose one of the candidate words in :possibleSecretWords
; to be this game's secret word
to pickSecretWord
  ;... to be supplied ...
  output "secret
  end


to main
  home clean hideturtle
  setlabelfont sansSerif
  make "gameOver "false
  make "badGuessCount 0
  make "guessedChars "
  drawGallows
  make "secretWord pickSecretWord
  drawEmptyGuessWord count :secretWord
  end

main