6
$\begingroup$

I am trying to create a user-friendly hangman game, but after attempting for some time, I am resorting to help here.

The basic idea is what I have a different categories to choose from:

 a = {"ALLIGATOR", "ANT", "BEAR", "BEE", "BIRD", "CAMEL", "CAT",m"CHEETAH", "CHICKEN","CHIMPANZEE", "COW", "CROCODILE", "DEER","DOG", "DOLPHIN", "DUCK", "EAGLE"}
 b = {"PHOENIX", "ARA", "CARINA", "NORMA", "ANDROMEDA", "ANTLIA", "APUS", "AQUARIUS", "AQUILA", "ARIES", "AURIGA", "BOÖTES", "CAELUM","CAMELOPARDALIS", "CANCER"}
 c = {"ANKLE", "ARM", "BACK", "BEARD", "BLOOD", "BODY", "BONE", "BRAIN", "CHEEK", "CHEST", "CHIN", "EAR", "EARS", "ELBOW", "EYE", "EYES", "FACE", "FEET", "FINGER"}
 d = {"NEW YORK", "LOS ANGELES", "CHICAGO", "HOUSTON", "PHOENIX", "PHILADELPHIA", "SANANTONIO", "DALLAS", "SAN DIEGO", "SAN JOSE", "DETROIT", "SAN FRANCISCO"}
 e = {"AFGHANISTAN", "ALBANIA", "ALGERIA", "AMERICAN SAMOA", "ANDORRA","ANGOLA", "ANGUILLA", "ARGENTINA", "ARMENIA", "ARUBA", "AUSTRALIA","AUSTRIA"}

This code then creates the "hangman" figure himself along with the frame he hangs from, called a "gallows"

 head = Graphics[{ Thick, Circle[]}]; 
 body = Graphics[{ Thick, Line[{{0, -1}, {0, -4}}]}]; 
 leg1 = Graphics[{ Thick, Line[{{0, -4}, {-1, -5}}]}]; 
 foot1 = Graphics[{ Thick, Line[{{1, -5}, {1.5, -4.75}}]}]; 
 foot2 = Graphics[{ Thick, Line[{{-1, -5}, {-1.5, -4.75}}]}]; 
 leg2 = Graphics[{ Thick, Line[{{0, -4}, {1, -5}}]}]; 
 arm1 = Graphics[{ Thick, Line[{{0, -2}, {-1, -1}}]}]; 
 arm2 = Graphics[{ Thick, Line[{{0, -2}, {1, -1}}]}];
 eye1 = Graphics[{PointSize[Large], Point[{-.4, .1}]}];
 eye2 = Graphics[{PointSize[Large], Point[{.4, .1}]}];
 frown = Graphics[{Thick, Line[{{.4, -.4}, {-.4, -.4}}]}];
 face = {eye1, eye2, frown};
 medleg = {leg1, foot1};
 medleg2 = {leg2, foot2};
 arm = {arm1, arm2};
 eyes = {eye1, eye2};
 legs = {leg1, leg2, foot1, foot2};
 gallows = Graphics[{Thickness[.02],Line[{{0, 1}, {0, 2}, {0, 2}, {-4, 2}, {-4,2}, {-4, -7}, {-8, -7}, {0, -7}}]}];
 easybodyparts = {head, body, arm1, arm2, leg1, leg2, foot1, foot2, eye1, eye2, frown};
 bodycount = {};

Now up to this point I'm good, however I am having some trouble here:

 theCat = Input["What category of word would you like: 
 a. Animals 
 b. Constellations
 c. Parts of the body
 d. Cities 
 e. Countries"];
 word = RandomChoice[theCat];
 stringWord = Riffle[Characters[word], " ", {1, -1, 2}];
 letters = Characters["ABCDEFGHIJKLMNOPQRSTUVWXYZ"];

 hideLetters = StringReplace[#, Table[letters[[i]] -> "_", {i, 1, 26}]] &;
 hideLetters[stringWord]
 k = 1;
 While[k <= Length[easybodyparts], 
 letter = InputString["What letter would you like to guess? You options are A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z:"];
  If[StringContainsQ[word, letter, IgnoreCase -> True], Print[letter], 
  AppendTo[bodycount, easybodyparts[[k]]]; 
  Print[Dynamic[Refresh[Show[gallows, bodycount]], k]]; k++]]

Basically, the user is prompted with a question as to which category they want to choose and then a random word is chosen and is put on the screen like this:

$$\{ ,\_, ,\_, ,\_, ,\_, ,\_, \}$$

Then the Input window appears (repeatedly) and asks user the letter they want to guess next. If guessed incorrectly, the hangman body will appear piece by piece; however if I guess the letter correctly, no body pieces are added (which is good), but no letter is placed anywhere (which is not good). Here is a sample of a head being produced on a missed letter. It would be ideal to somehow produce $\{ ,\_, ,\_, ,\_, ,\_, ,\_, \}$ near the hangman character, but I don't know if that's possible.

enter image description here

In addition, there are 3 hangman plots that generate simultaneously with this code, when I obviously want only 1. I'm also looking for a way to print each letter in the right place. For an example, "E" would be placed as _ E _ for the word red. And once that letter is used there is no way to use it again. I feel like people will wish to close this because it is more so a personal matter and I don't know if it could help a lot of others, but the usage of loops and many other useful commands is presented throughout this task. Lastly, instead of the "what letter would you like to guess" Input window, I was trying to create a palette/button menu where a user could push those instead. I just need some help and understand this is quite lengthy but I have supplied all that I can figure out thus far, in this "somewhat" created game of hangman.

Thanks for any advice or help, and I will try my best to supply any explanations if anyone has questions. I know I asked a few questions, but at this point I don't have anyone to really help me out. There is hangman games done in Mathematica on the "Wolfram Demonstration" site, but I don't want to copy those, I've used a few as references though.

**250 rep to whomever can edit my code, OR the code in the comment below provided by a community member. Bounty opens in ~ 9 hours **

$\endgroup$
11
$\begingroup$

Here is just for illustration using words in e. I leave it to others to make random choice from word sets and how to terminate when either success or failure. I do not have time to refine at present. Perhaps others can adapt.

com[a_, b_, c_] := 
 Thread[{a, b, c}] /. {{"_", x_, x_} :> x, {x_, x_, _} :> 
    x, {"_", x_, y_} :> "_"}
fun[wd_, guess_, pos_] := Module[
  {lg = StringLength[wd]},
  com[pos, Characters[wd], Table[guess, lg]]]
Manipulate[
 Module[{p = Table["_", StringLength[wd]], 
   hangman = {Line[{{-1, 0}, {1, 0}}],
     Line[{{0, 0}, {0, 2}}],
     Line[{{0, 2}, {1/2, 2}}],
     Line[{{1/2, 2}, {1/2, 1.8}}],
     Circle[{1/2, 1.6}, 0.2],
     Line[{{1/2, 1.4}, {1/2, 1}}],
     Line[{{1/2, 1}, {1/4, 1/2}}],
     Line[{{1/2, 1}, {3/4, 1/2}}],
     Line[{{1/4, 1.3}, {1/2, 1.3}}],
     Line[{{1/2, 1.3}, {3/4, 1.3}}]
     }, wrong, res, gr},
  res = Row[Fold[fun[wd, #2, #1] &, p, cr]];
  wrong = Total[1 - Boole[MemberQ[Characters[wd], #]] & /@ cr];

  Column[{If[StringJoin @@ res == wd, 
     Row[{Style[res, Red], " :  Success!"}], res],
    Graphics[hangman[[1 ;; wrong]], PlotRange -> {0, 3}],
    If[wrong >= Length[hangman], "May God have mercy on your soul", 
     ""],}]
  ],

 {wd, e},
 {{cr, {""}, "Choose a letter"}, CharacterRange["A", "Z"], CheckboxBar}
 ] 

enter image description here

enter image description here

$\endgroup$
  • 1
    $\begingroup$ I really appreciate you taking your personal time to illustrate this concept $\endgroup$ – Brandon Dec 7 '16 at 3:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.