// =======================================================================================
// This sketch allows you to play hangman on your Arduino. There is a small list of words
// defined in a variable, which the program randomly selects from. A potentiometer is used
// for scrolling through the alphabet and a tactile switch for making selections. When you
// select the letter, the program displays a * instead of the letter and you aren't allowed
// to make that selection again. If you guess the word, you win and the board is reset. If
// you guess too many wrong, game over and the board is reset. If you hold the select button
// for 2 seconds, the board is reset.
//
// For more information, please visit my website: www.nerdybynature.com
//
// Written By: Dan Wagoner
// Date: 08/22/2009
//
//
// References
// ----------------------------------------------------------------------------------------
// Debounce code from David A. Mellis' / Limor Fried example in the Arduino examples
// String library written by Hernando Barragan - http://www.arduino.cc/en/Tutorial/TextString
//
#include <LiquidCrystal.h>
#define SPEAKERPIN 3
#define NUMWORDS 10
//define notes for buzzer
#define LOWNOTE 100
#define ALOW 440
#define CLOW 261
#define ELOW 329
#define FLOW 349
#define CHIGH 523
#define EHIGH 659
#define GHIGH 784
#define FSHIGH 740
#define AHIGH 880
#define btnRight 0
#define btnUp 1
#define btnDown 2
#define btnLeft 3
#define btnSelect 4
#define btnNone 5
void(* resetFunc) (void) = 0; //declare reset function @ address 0
const char* words[] = {"atmosphere", "verbatim", "postscript", "deadline", "censorship", "shorthand", "monkey", "dickhead", "dilemma", "interface"};
const char letterVal[] = "abcdefghijklmnopqrstuvwxyz";
char guessLetter;
char guessLast;
char guessed[25];
char* secretWord;
int guessedCount = 1;
int wordSize;
int gotOne = 0;
int alreadyGuessed = 0;
int showAsterisk = 0;
int buttonState;
int hangman = 0;
int totalRight = 0;
int sel = 0;
int prevKey = btnNone;
unsigned long lastDebounceTime = 0;
//LiquidCrystal lcd(12, 11, 2, 7, 8, 9, 10);
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
String guessWord = String(10);
// hangman graphic characters
byte topleft[] = { 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
byte topright[] = { 0x1C, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte bottomleft[] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x1F };
byte bottomright[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte head[] = { 0x1C, 0x04, 0x04, 0x0E, 0x0E, 0x00, 0x00, 0x00 };
byte topbody[] = { 0x1C, 0x04, 0x04, 0x0E, 0x0E, 0x04, 0x04, 0x04 };
byte bottombody[] = { 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte rightarm[] = { 0x1C, 0x04, 0x04, 0x0E, 0x0E, 0x05, 0x06, 0x04 };
byte leftarm[] = { 0x1C, 0x04, 0x04, 0x0E, 0x0E, 0x15, 0x0E, 0x04 };
byte rightleg[] = { 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00 };
byte leftleg[] = { 0x04, 0x04, 0x0A, 0x0A, 0x11, 0x00, 0x00, 0x00 };
byte leftarrow[] = { 0x10, 0x18, 0x1C, 0x1E, 0x1E, 0x1C, 0x18, 0x10 };
byte rightarrow[] = { 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x07, 0x03, 0x01 };
void setup()
{
Serial.begin(9600);
pinMode (SPEAKERPIN, OUTPUT);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("HANGMANDUINO");
delay(2000);
// pick a random word using analog 5 for random data
randomSeed(analogRead(5));
newWord();
//draw the board
draw_board();
}
void newWord() {
//pick a random word from the list
int pick = random(NUMWORDS);
const char* pickWord = words[pick];
guessWord = pickWord;
//secretWord = guessWord.getChars();
wordSize = guessWord.length();
Serial.println(guessWord); // print the word to serial for cheaters like me ;)
}
void draw_board() {
// define the custom characters
lcd.createChar(0, topleft);
lcd.createChar(1, topright);
lcd.createChar(2, bottomleft);
lcd.createChar(3, bottomright);
lcd.createChar(4, leftarrow);
lcd.createChar(5, rightarrow);
// draw blank hangman table
lcd.clear();
lcd.home();
lcd.write(byte(0));
lcd.write(1);
lcd.setCursor(0, 1);
lcd.write(2);
lcd.write(3);
// print underlines
lcd.setCursor(3, 1);
for (int x = 0; x < wordSize; x++) {
lcd.print("_");
}
}
void loop() {
// letter selection via potentiometer
//int potVal = analogRead(POTPIN) / 40; // 1024 / 26 ~= 39
int potVal = sel; //Hack to use lcd keypad shield buttons
guessLetter = letterVal[potVal];
// if letter is different from last, print to lcd
// this prevents from printing the same char over and over
if (guessLetter != guessLast) {
guessLast = guessLetter;
showAsterisk = 0;
// cycle through all guessed letters and determine whether to show * or the letter
for (int x = 0; x < guessedCount; x++) {
if (guessLetter == guessed[x]) {
showAsterisk = 1;
}
}
// print letters to the left of selected letter
lcd.setCursor(3, 0);
for (int x = 5; x >= 1 ; x--) {
if (potVal - x >= 0) {
lcd.print(letterVal[potVal - x]);
}
else {
lcd.print("|");
}
}
// print left arrow
lcd.write(4);
// print the letter
if (showAsterisk == 0) {
lcd.setCursor(9, 0);
lcd.print(guessLetter);
alreadyGuessed = 0;
}
// print a *
else {
lcd.setCursor(9, 0);
lcd.print("*");
alreadyGuessed = 1;
}
// print right arrow
lcd.write(5);
// print letters to the right of selected letter
lcd.setCursor(11, 0);
for (int x = 1; x <= 5 ; x++) {
if (potVal + x <= 25) {
lcd.print(letterVal[potVal + x]);
}
else {
lcd.print("|");
}
}
}
int k = inkeys();
if ( k == btnSelect ) {
gotOne = 0;
if (alreadyGuessed == 0) {
alreadyGuessed = 1;
lcd.setCursor(9, 0);
lcd.print("*");
char buf[wordSize+1];
guessWord.toCharArray(buf,wordSize+1);
for (int i = 0; i < wordSize; i++) {
if (buf[i] == guessLetter) {
lcd.setCursor(i + 3, 1);
lcd.print(guessLetter);
gotOne = 1;
totalRight = totalRight + 1;
}
}
// add letter to guessed letter array
guessed[guessedCount] = guessLetter;
guessedCount++;
// none of the letters match, draw the next body part on the hangman
if (gotOne == 0) {
buzz(LOWNOTE, 500);
hangman++;
draw_hangman(hangman);
}
else {
// letter is in word, sound buzzer
buzz(FSHIGH, 30);
buzz(AHIGH, 50);
}
//all letters have been guessed...WIN!
if (totalRight == wordSize) {
gameOver(1);
}
}
// this letter has already been guessed, sound buzzer
} else if (k == btnRight) {
if (sel > 24) {
sel = 0;
} else {
sel++;
}
} else if (k == btnLeft) {
if (sel <= 0) {
sel = 25;
} else {
sel--;
}
}
}
void draw_hangman(int var) {
switch (var) {
case 1:
lcd.createChar(1, head); // head
break;
case 2:
lcd.createChar(1, topbody); // body
lcd.createChar(3, bottombody);
break;
case 3:
lcd.createChar(1, rightarm); // right arm
break;
case 4:
lcd.createChar(1, leftarm); // left arm
break;
case 5:
lcd.createChar(3, rightleg); // right leg
break;
case 6:
lcd.createChar(3, leftleg); // left leg
break;
case 7:
gameOver(0);
default:
break;
}
}
void gameOver(int whatToDo) {
// decide whether win, lose or restart game
switch (whatToDo) {
case 0: // GAME OVER
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("GAME");
lcd.setCursor(6, 1);
lcd.print("OVER");
//buzzer sound
buzz(ELOW, 500); // GAME OVER!
buzz(CLOW, 1000); // sound buzzer
break;
case 1: // WINNER
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("HANGMAN");
lcd.setCursor(4, 1);
lcd.print("MASTER!");
// buzzer sound
buzz(ALOW, 150);
buzz(CHIGH, 150);
buzz(EHIGH, 150);
buzz(AHIGH, 150);
delay(150);
buzz(GHIGH, 150);
buzz(AHIGH, 500);
}
delay(2000);
resetFunc(); // reset arduino for a new game
}
void buzz (int frequencyInHertz, long timeInMilliseconds) {
Serial.println(frequencyInHertz);
long delayAmount = (long)(1000000 / frequencyInHertz);
long loopTime = (long)((timeInMilliseconds * 1000) / (delayAmount * 2));
for (int x = 0; x < loopTime; x++) {
digitalWrite(SPEAKERPIN, HIGH);
delayMicroseconds(delayAmount);
digitalWrite(SPEAKERPIN, LOW);
delayMicroseconds(delayAmount);
}
delay(20);
}
int getKey() {
int b = analogRead(A0);
if (b > 1000) return btnNone;
delay(8);
if (b < 50) return btnRight;
if (b < 180) return btnUp;
if (b < 330) return btnDown;
if (b < 520) return btnLeft;
if (b < 700) return btnSelect;
}
int inkeys() {
int k = getKey();
while (k == btnNone) {
k = getKey();
delay(10);
}
delay(200); //debounce
return k;
}
Intuitive Machines™ Biotronics™ Zoikrons™ Autognorics™ ELFS™ IM™
are original trademarks and logos
solely distributed by
L.A.W.S.I.N.

Comments
Post a Comment