Advertisement
Guest User

Untitled

a guest
May 24th, 2012
653
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.72 KB | None | 0 0
  1. using System.Drawing.Imaging;
  2. using System;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Web.Mvc;
  6.  
  7. namespace Blah
  8. {
  9.     public class HangmanController : Controller
  10.     {
  11.         public ActionResult Index()
  12.         {
  13.             var game = Session["hangman"] as HangmanGame ?? HangmanGame.New();
  14.  
  15.             game = ExecuteGameCommand(game);
  16.  
  17.             Session["hangman"] = game;
  18.  
  19.             var imageRenderer = new HangmanImageRenderer(game);
  20.             return new ImageResult(imageRenderer.Render());
  21.         }
  22.  
  23.         private HangmanGame ExecuteGameCommand(HangmanGame game)
  24.         {
  25.             var referrerQuery = Request.UrlReferrer != null ? Request.UrlReferrer.Query : string.Empty;
  26.  
  27.             if (referrerQuery.Contains("_new_hangman_"))
  28.                 return HangmanGame.New();
  29.  
  30.             if (game.IsOver())
  31.                 return game;
  32.  
  33.             var chosenLetter = HangmanGame.ValidLetters
  34.                 .FirstOrDefault(letter => referrerQuery.Contains(String.Format("_hangman_{0}_", letter)));
  35.  
  36.             if (chosenLetter != default(char))
  37.                 game.RegisterGuess(chosenLetter);
  38.  
  39.             return game;
  40.         }
  41.     }
  42.  
  43.     public class HangmanImageRenderer
  44.     {
  45.         private const int ImageWidth = 500;
  46.         private const int ImageHeight = 150;
  47.         private const int LetterDistance = 10;
  48.  
  49.         private static readonly Pen Pen = new Pen(Brushes.Black, 3);
  50.         private static readonly Font Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
  51.         private static readonly Font MonospaceFont = new Font(FontFamily.GenericMonospace, 10, FontStyle.Regular);
  52.         private static readonly Font TitleFont = new Font(FontFamily.GenericSansSerif, 15, FontStyle.Bold);
  53.  
  54.         private readonly HangmanGame _game;
  55.  
  56.         public HangmanImageRenderer(HangmanGame game)
  57.         {
  58.             _game = game;
  59.         }
  60.  
  61.         public Image Render()
  62.         {
  63.             var image = new Bitmap(ImageWidth, ImageHeight);
  64.  
  65.             using (var g = Graphics.FromImage(image))
  66.             {
  67.                 DrawWhiteCanvas(g);
  68.                 DrawBorder(g);
  69.                 WriteTitle(g);
  70.  
  71.                 DrawHang(g);
  72.                 DrawMan(g);
  73.  
  74.                 DrawUsedLetters(g);
  75.  
  76.                 DrawPuzzleText(g, _game.Guessed);
  77.  
  78.                 if (_game.IsWon())
  79.                     DrawGameWonMessage(g);
  80.  
  81.                 if (_game.IsLost())
  82.                 {
  83.                     DrawGameLostMessage(g);
  84.                     DrawPuzzleText(g, _game.Solution);
  85.                 }
  86.             }
  87.  
  88.             return image;
  89.         }
  90.  
  91.         private static void DrawWhiteCanvas(Graphics g)
  92.         {
  93.             g.FillRectangle(Brushes.White, 0, 0, ImageWidth, ImageHeight);
  94.         }
  95.  
  96.         private static void DrawBorder(Graphics g)
  97.         {
  98.             g.DrawRectangle(Pen, 0, 0, ImageWidth, ImageHeight);
  99.         }
  100.  
  101.         private static void WriteTitle(Graphics g)
  102.         {
  103.             g.DrawString("StackExchange Hangman", TitleFont, Brushes.DodgerBlue, 10, 10);
  104.         }
  105.  
  106.         private static void DrawHang(Graphics g)
  107.         {
  108.             g.DrawLine(Pen, 400, 10, 400, 15);
  109.             g.DrawLine(Pen, 400, 10, 475, 10);
  110.             g.DrawLine(Pen, 475, 10, 475, 110);
  111.         }
  112.  
  113.         private void DrawMan(Graphics g)
  114.         {
  115.             if (_game.WrongAttempts > 0)
  116.             {
  117.                 g.DrawArc(Pen, 390, 15, 20, 20, 0, 360);
  118.                 g.DrawLine(Pen, 397, 20, 397, 25);
  119.                 g.DrawLine(Pen, 403, 20, 403, 25);
  120.             }
  121.  
  122.             if (_game.WrongAttempts > 1)
  123.                 g.DrawLine(Pen, 400, 35, 400, 75);
  124.  
  125.             if (_game.WrongAttempts > 2)
  126.                 g.DrawLine(Pen, 400, 40, 380, 60);
  127.  
  128.             if (_game.WrongAttempts > 3)
  129.                 g.DrawLine(Pen, 400, 40, 420, 60);
  130.  
  131.             if (_game.WrongAttempts > 4)
  132.                 g.DrawLine(Pen, 400, 75, 380, 105);
  133.  
  134.             if (_game.WrongAttempts > 5)
  135.                 g.DrawLine(Pen, 400, 75, 420, 105);
  136.         }
  137.  
  138.         private void DrawUsedLetters(Graphics g)
  139.         {
  140.             if (String.IsNullOrEmpty(_game.UsedLetters))
  141.                 return;
  142.  
  143.             g.DrawString(
  144.                 "Used Letters: " + String.Join(",", _game.UsedLetters.Select(c => c).OrderBy(c => c)),
  145.                 Font,
  146.                 Brushes.DarkGray,
  147.                 10, 100);
  148.         }
  149.  
  150.         private static void DrawPuzzleText(Graphics g, string text)
  151.         {
  152.             for (var i = 0; i < text.Length; i++)
  153.             {
  154.                 g.DrawString(
  155.                     text.Substring(i, 1),
  156.                     MonospaceFont, Brushes.Black, (i + 1) * LetterDistance, 125);
  157.             }
  158.         }
  159.  
  160.         private static void DrawGameWonMessage(Graphics g)
  161.         {
  162.             g.DrawString("Contratulations! You won!", TitleFont, Brushes.DarkGreen, 10, 55);
  163.         }
  164.  
  165.         private static void DrawGameLostMessage(Graphics g)
  166.         {
  167.             g.DrawString("You lost!", TitleFont, Brushes.DarkRed, 10, 55);
  168.         }
  169.     }
  170.  
  171.     [Serializable]
  172.     public class HangmanGame
  173.     {
  174.         public const string ValidLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  175.  
  176.         public string Solution { get; set; }
  177.         public string Guessed { get; set; }
  178.         public string UsedLetters { get; set; }
  179.         public int WrongAttempts { get; set; }
  180.  
  181.         public static HangmanGame New()
  182.         {
  183.             var randomWord = Dictionary[new Random().Next(Dictionary.Length)].ToUpperInvariant();
  184.  
  185.             return new HangmanGame
  186.                     {
  187.                         Solution = randomWord,
  188.                         Guessed = MaskLetters(randomWord),
  189.                         UsedLetters = String.Empty,
  190.                         WrongAttempts = 0
  191.                     };
  192.         }
  193.  
  194.         private static string MaskLetters(string source)
  195.         {
  196.             return new String(source.Select(c => char.IsLetter(c) ? '_' : c).ToArray());
  197.         }
  198.  
  199.         public void RegisterGuess(char chosenLetter)
  200.         {
  201.             if (!ValidLetters.Contains(chosenLetter) ||
  202.                 UsedLetters.Contains(chosenLetter))
  203.                 return;
  204.  
  205.             UsedLetters += chosenLetter;
  206.  
  207.             if (!Solution.Contains(chosenLetter))
  208.                 WrongAttempts++;
  209.             else
  210.                 Guessed = new string(
  211.                     Solution.Zip(Guessed, (s, g) => s == chosenLetter ? chosenLetter : g).ToArray());
  212.         }
  213.  
  214.         public bool IsOver()
  215.         {
  216.             return IsWon() || IsLost();
  217.         }
  218.  
  219.         public bool IsWon()
  220.         {
  221.             return !Guessed.Contains('_');
  222.         }
  223.  
  224.         public bool IsLost()
  225.         {
  226.             return WrongAttempts > 5;
  227.         }
  228.  
  229.         private static readonly string[] Dictionary = new[]
  230.                 {
  231.                     "Stack Overflow", "Server Fault", "Super User", "Meta Stack Overflow"
  232.                     , "Web Applications", "Gaming", "Webmasters",
  233.                     "Cooking", "Game Development", "Photography", "Statistical Analysis",
  234.                     "Mathematics", "Home Improvement", "GIS",
  235.                     "TeX - LaTeX", "Ask Ubuntu", "Personal Finance and Money",
  236.                     "English Language and Usage", "Stack Apps",
  237.                     "User Experience", "Unix and Linux", "WordPress",
  238.                     "Theoretical Computer Science", "Apple", "Role-playing Games",
  239.                     "Bicycles", "Programmers", "Electrical Engineering",
  240.                     "Android Enthusiasts", "OnStartups", "Board and Card Games",
  241.                     "Physics", "Homebrewing", "IT Security", "Writers",
  242.                     "Audio-Video Production", "Graphic Design",
  243.                     "Database Administrators", "Science Fiction and Fantasy",
  244.                     "Code Review", "Code Golf", "Quantitative Finance",
  245.                     "Project Management", "Skeptics", "Fitness and Nutrition",
  246.                     "Drupal Answers",
  247.                     "Motor Vehicle Maintenance and Repair", "Parenting", "SharePoint",
  248.                     "Musical Practice and Performance",
  249.                     "Software Quality Assurance and Testing", "Mi Yodeya",
  250.                     "German Language and Usage", "Japanese Language and Usage",
  251.                     "Philosophy", "Gardening and Landscaping", "Travel",
  252.                     "Personal Productivity", "Cryptography", "Signal Processing",
  253.                     "French Language and Usage", "Christianity", "Bitcoin", "Linguistics"
  254.                     , "Biblical Hermeneutics", "History",
  255.                     "LEGO® Answers", "Spanish Language and Usage",
  256.                     "Computational Science", "Movies and TV",
  257.                     "Chinese Language and Usage", "Biology", "Poker", "Mathematica",
  258.                     "Cognitive Sciences", "The Great Outdoors",
  259.                     "SmugMug", "Martial Arts", "Sports", "Academia", "Computer Science",
  260.                     "The Workplace", "Windows Phone",
  261.                     "Chemistry", "Chess"
  262.                 };
  263.     }
  264.  
  265.     public class ImageResult : ActionResult
  266.     {
  267.         public ImageResult(Image image)
  268.         {
  269.             if (image == null)
  270.                 throw new ArgumentNullException("image");
  271.  
  272.             _image = image;
  273.         }
  274.  
  275.         private readonly Image _image;
  276.  
  277.         public override void ExecuteResult(ControllerContext context)
  278.         {
  279.             if (context == null)
  280.                 throw new ArgumentNullException("context");
  281.  
  282.             var response = context.HttpContext.Response;
  283.  
  284.             response.ContentType = "image/gif";
  285.  
  286.             _image.Save(response.OutputStream, ImageFormat.Gif);
  287.             response.End();
  288.         }
  289.     }
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement