diff --git a/GildedRose/C/Makefile b/GildedRose/C/Makefile index 60d11871..3a695892 100644 --- a/GildedRose/C/Makefile +++ b/GildedRose/C/Makefile @@ -22,7 +22,7 @@ CPPFLAGS += -I$(CPPUTEST_HOME)/include # Flags passed to the C++ compiler. CFLAGS += -g -Wall -Wextra -LD_LIBRARIES = -L$(CPPUTEST_HOME)/lib -lCppUTest -lCppUTestExt +LD_LIBRARIES = -L$(CPPUTEST_HOME)/lib -lCppUTest # All tests produced by this Makefile. Remember to add new tests you # created to the list. diff --git a/GildedRose/Java/GildedRose.java b/GildedRose/Java/com/gildedrose/GildedRose.java similarity index 98% rename from GildedRose/Java/GildedRose.java rename to GildedRose/Java/com/gildedrose/GildedRose.java index 9f407310..8acc098d 100755 --- a/GildedRose/Java/GildedRose.java +++ b/GildedRose/Java/com/gildedrose/GildedRose.java @@ -1,3 +1,4 @@ +package com.gildedrose; class GildedRose { Item[] items; diff --git a/GildedRose/Java/GildedRoseTest.java b/GildedRose/Java/com/gildedrose/GildedRoseTest.java similarity index 92% rename from GildedRose/Java/GildedRoseTest.java rename to GildedRose/Java/com/gildedrose/GildedRoseTest.java index 6a21ee64..49517932 100644 --- a/GildedRose/Java/GildedRoseTest.java +++ b/GildedRose/Java/com/gildedrose/GildedRoseTest.java @@ -1,3 +1,4 @@ +package com.gildedrose; import static org.junit.Assert.*; import org.junit.Test; diff --git a/GildedRose/Java/Item.java b/GildedRose/Java/com/gildedrose/Item.java similarity index 93% rename from GildedRose/Java/Item.java rename to GildedRose/Java/com/gildedrose/Item.java index 8c846b45..779aad79 100755 --- a/GildedRose/Java/Item.java +++ b/GildedRose/Java/com/gildedrose/Item.java @@ -1,3 +1,4 @@ +package com.gildedrose; public class Item { public String name; diff --git a/GildedRose/Java/TexttestFixture.java b/GildedRose/Java/com/gildedrose/TexttestFixture.java similarity index 97% rename from GildedRose/Java/TexttestFixture.java rename to GildedRose/Java/com/gildedrose/TexttestFixture.java index 3f48d3aa..bd6a50ce 100755 --- a/GildedRose/Java/TexttestFixture.java +++ b/GildedRose/Java/com/gildedrose/TexttestFixture.java @@ -1,3 +1,4 @@ +package com.gildedrose; public class TexttestFixture { public static void main(String[] args) { diff --git a/GildedRose/README.md b/GildedRose/README.md index 09d6f98e..39e1616e 100644 --- a/GildedRose/README.md +++ b/GildedRose/README.md @@ -1,6 +1,12 @@ -This Kata was originally created by Terry Hughes (http://twitter.com/#!/TerryHughes). It is already on GitHub [here](https://github.com/NotMyself/GildedRose). I could have forked it again, but I thought other language users might not want to download a whole C# project environment. In this repository are starting code samples for Java, Python, Ruby, Smalltalk, C#, C and C++. +This Kata was originally created by Terry Hughes (http://twitter.com/#!/TerryHughes). It is already on GitHub [here](https://github.com/NotMyself/GildedRose). See also [Bobby Johnson's description of the kata](http://iamnotmyself.com/2011/02/13/refactor-this-the-gilded-rose-kata/). -See also http://iamnotmyself.com/2011/02/13/refactor-this-the-gilded-rose-kata/ +I translated the original C# into a few other languages, (with a little help from my friends!), and slightly changed the starting position. This means I've actually done a small amount of refactoring already compared with the original form of the kata, and made it easier to get going with writing tests by giving you one failing unit test to start with. I also added test fixtures for Text-Based approval testing with TextTest (see [the TextTests](https://github.com/emilybache/Refactoring-Katas/tree/master/GildedRose/texttests)) + +As Bobby Johnson points out in his article ["Why Most Solutions to Gilded Rose Miss The Bigger Picture"](http://iamnotmyself.com/2012/12/07/why-most-solutions-to-gilded-rose-miss-the-bigger-picture/), it'll actually give you +better practice at handling a legacy code situation if you do this Kata in the original C#. However, I think this kata +is also really useful for practicing writing good tests using different frameworks and approaches, and the small changes I've made help with that. I think it's also interesting to compare what the refactored code and tests look like in different programming languages. + +I wrote this article ["Writing Good Tests for the Gilded Rose Kata"](http://emilybache.blogspot.se/2013/03/writing-good-tests-for-gilded-rose-kata.html) about how you could use this kata in a [coding dojo](https://leanpub.com/codingdojohandbook). ## How to use this Kata @@ -10,17 +16,6 @@ You could write some unit tests yourself, using the requirements to identify sui Alternatively, use the "Text-Based" tests provided in this repository. (Read more about that in the next section) -I've also set this kata up on [cyber-dojo](http://cyber-dojo.com) for several languages, so you can get going really quickly: - -- [Cucumber, Java](http://cyber-dojo.com/forker/fork/0F82D4BA89?avatar=gorilla&tag=45) - for this one I've also written some step definitions for you -- [JUnit, Java](http://cyber-dojo.com/forker/fork/751DD02C4C?avatar=snake&tag=4) -- [C#](http://cyber-dojo.com/forker/fork/107907AD1E?avatar=alligator&tag=13) -- [Ruby](http://cyber-dojo.com/forker/fork/A8943EAF92?avatar=hippo&tag=9) -- [RSpec, Ruby](http://cyber-dojo.com/forker/fork/8E58B0AD16?avatar=raccoon&tag=3) -- [Python](http://cyber-dojo.com/forker/fork/297041AA7A?avatar=lion&tag=4) - - - Whichever testing approach you choose, the idea of the exercise is to do some deliberate practice, and improve your skills at designing test cases and refactoring. The idea is not to re-write the code from scratch, but rather to practice designing tests, taking small steps, running the tests often, and incrementally improving the design. ## Text-Based Approval Testing @@ -33,3 +28,13 @@ Typically a piece of legacy code may not produce suitable textual output from th The Text-Based tests in this repository are designed to be used with the tool "TextTest" (http://texttest.org). This tool helps you to organize and run text-based tests. There is more information in the README file in the "texttests" subdirectory. +## Get going quickly using Cyber-Dojo + +I've also set this kata up on [cyber-dojo](http://cyber-dojo.com) for several languages, so you can get going really quickly: + +- [JUnit, Java](http://cyber-dojo.com/forker/fork/751DD02C4C?avatar=snake&tag=4) +- [C#](http://cyber-dojo.com/forker/fork/107907AD1E?avatar=alligator&tag=13) +- [Ruby](http://cyber-dojo.com/forker/fork/A8943EAF92?avatar=hippo&tag=9) +- [RSpec, Ruby](http://cyber-dojo.com/forker/fork/8E58B0AD16?avatar=raccoon&tag=3) +- [Python](http://cyber-dojo.com/forker/fork/297041AA7A?avatar=lion&tag=4) +- [Cucumber, Java](http://cyber-dojo.com/forker/fork/0F82D4BA89?avatar=gorilla&tag=45) - for this one I've also written some step definitions for you diff --git a/GildedRose/csharp/ApprovalTest.cs b/GildedRose/csharp/ApprovalTest.cs new file mode 100644 index 00000000..ad294419 --- /dev/null +++ b/GildedRose/csharp/ApprovalTest.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; +using System.Text; +using GildedRose; +using NUnit.Framework; +using ApprovalTests; +using ApprovalTests.Reporters; + +namespace GildedRoseTests +{ + [TestFixture] + [UseReporter(typeof(NUnitReporter))] + public class ApprovalTest + { + [Test] + public void ThirtyDays() + { + StringBuilder fakeoutput = new StringBuilder(); + Console.SetOut(new StringWriter(fakeoutput)); + Console.SetIn(new StringReader("a\n")); + + Program.Main(new string[] { }); + String output = fakeoutput.ToString(); + Approvals.Verify(output); + } + } + +} \ No newline at end of file diff --git a/GildedRose/csharp/GildedRose.cs b/GildedRose/csharp/GildedRose.cs new file mode 100644 index 00000000..a0017b2e --- /dev/null +++ b/GildedRose/csharp/GildedRose.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; + +namespace GildedRose +{ + class GildedRose + { + IList Items; + public GildedRose(IList Items) + { + this.Items = Items; + } + + public void UpdateQuality() + { + for (var i = 0; i < Items.Count; i++) + { + if (Items[i].Name != "Aged Brie" && Items[i].Name != "Backstage passes to a TAFKAL80ETC concert") + { + if (Items[i].Quality > 0) + { + if (Items[i].Name != "Sulfuras, Hand of Ragnaros") + { + Items[i].Quality = Items[i].Quality - 1; + } + } + } + else + { + if (Items[i].Quality < 50) + { + Items[i].Quality = Items[i].Quality + 1; + + if (Items[i].Name == "Backstage passes to a TAFKAL80ETC concert") + { + if (Items[i].SellIn < 11) + { + if (Items[i].Quality < 50) + { + Items[i].Quality = Items[i].Quality + 1; + } + } + + if (Items[i].SellIn < 6) + { + if (Items[i].Quality < 50) + { + Items[i].Quality = Items[i].Quality + 1; + } + } + } + } + } + + if (Items[i].Name != "Sulfuras, Hand of Ragnaros") + { + Items[i].SellIn = Items[i].SellIn - 1; + } + + if (Items[i].SellIn < 0) + { + if (Items[i].Name != "Aged Brie") + { + if (Items[i].Name != "Backstage passes to a TAFKAL80ETC concert") + { + if (Items[i].Quality > 0) + { + if (Items[i].Name != "Sulfuras, Hand of Ragnaros") + { + Items[i].Quality = Items[i].Quality - 1; + } + } + } + else + { + Items[i].Quality = Items[i].Quality - Items[i].Quality; + } + } + else + { + if (Items[i].Quality < 50) + { + Items[i].Quality = Items[i].Quality + 1; + } + } + } + } + } + + } + + public class Item + { + public string Name { get; set; } + + public int SellIn { get; set; } + + public int Quality { get; set; } + } + +} diff --git a/GildedRose/csharp/GildedRoseTest.cs b/GildedRose/csharp/GildedRoseTest.cs new file mode 100644 index 00000000..02fd5b21 --- /dev/null +++ b/GildedRose/csharp/GildedRoseTest.cs @@ -0,0 +1,19 @@ +using System; +using NUnit.Framework; +using System.Collections.Generic; + +namespace GildedRose +{ + [TestFixture()] + public class GildedRoseTest + { + [Test()] + public void foo() { + IList Items = new List { new Item{Name = "foo", SellIn = 0, Quality = 0} }; + GildedRose app = new GildedRose(Items); + app.UpdateQuality(); + Assert.AreEqual("fixme", Items[0].Name); + } + } +} + diff --git a/GildedRose/csharp/Program.cs b/GildedRose/csharp/Program.cs deleted file mode 100644 index 3ba8371e..00000000 --- a/GildedRose/csharp/Program.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System.Collections.Generic; - -namespace GildedRose.Console -{ - class Program - { - IList Items; - static void Main(string[] args) - { - System.Console.WriteLine("OMGHAI!"); - - var app = new Program() - { - Items = new List - { - new Item {Name = "+5 Dexterity Vest", SellIn = 10, Quality = 20}, - new Item {Name = "Aged Brie", SellIn = 2, Quality = 0}, - new Item {Name = "Elixir of the Mongoose", SellIn = 5, Quality = 7}, - new Item {Name = "Sulfuras, Hand of Ragnaros", SellIn = 0, Quality = 80}, - new Item {Name = "Sulfuras, Hand of Ragnaros", SellIn = -1, Quality = 80}, - new Item - { - Name = "Backstage passes to a TAFKAL80ETC concert", - SellIn = 15, - Quality = 20 - }, - new Item - { - Name = "Backstage passes to a TAFKAL80ETC concert", - SellIn = 10, - Quality = 49 - }, - new Item - { - Name = "Backstage passes to a TAFKAL80ETC concert", - SellIn = 5, - Quality = 49 - }, - // this conjured item does not work properly yet - new Item {Name = "Conjured Mana Cake", SellIn = 3, Quality = 6} - } - - }; - - for (var i = 0; i < 31; i++) - { - System.Console.WriteLine("-------- day " + i + " --------"); - System.Console.WriteLine("name, sellIn, quality"); - for (var j = 0; j < app.Items.Count; j++) - { - System.Console.WriteLine(app.Items[j].Name + ", " + app.Items[j].SellIn + ", " + app.Items[j].Quality); - } - System.Console.WriteLine(""); - app.UpdateQuality(); - } - System.Console.ReadKey(); - - } - - public void UpdateQuality() - { - for (var i = 0; i < Items.Count; i++) - { - if (Items[i].Name != "Aged Brie" && Items[i].Name != "Backstage passes to a TAFKAL80ETC concert") - { - if (Items[i].Quality > 0) - { - if (Items[i].Name != "Sulfuras, Hand of Ragnaros") - { - Items[i].Quality = Items[i].Quality - 1; - } - } - } - else - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - - if (Items[i].Name == "Backstage passes to a TAFKAL80ETC concert") - { - if (Items[i].SellIn < 11) - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - } - } - - if (Items[i].SellIn < 6) - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - } - } - } - } - } - - if (Items[i].Name != "Sulfuras, Hand of Ragnaros") - { - Items[i].SellIn = Items[i].SellIn - 1; - } - - if (Items[i].SellIn < 0) - { - if (Items[i].Name != "Aged Brie") - { - if (Items[i].Name != "Backstage passes to a TAFKAL80ETC concert") - { - if (Items[i].Quality > 0) - { - if (Items[i].Name != "Sulfuras, Hand of Ragnaros") - { - Items[i].Quality = Items[i].Quality - 1; - } - } - } - else - { - Items[i].Quality = Items[i].Quality - Items[i].Quality; - } - } - else - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - } - } - } - } - } - - } - - public class Item - { - public string Name { get; set; } - - public int SellIn { get; set; } - - public int Quality { get; set; } - } - -} diff --git a/GildedRose/csharp/TextTestFixture.cs b/GildedRose/csharp/TextTestFixture.cs new file mode 100644 index 00000000..3283aba9 --- /dev/null +++ b/GildedRose/csharp/TextTestFixture.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; + +namespace GildedRose +{ + class Program + { + public static void Main(string[] args) + { + System.Console.WriteLine("OMGHAI!"); + + IList Items = new List{ + new Item {Name = "+5 Dexterity Vest", SellIn = 10, Quality = 20}, + new Item {Name = "Aged Brie", SellIn = 2, Quality = 0}, + new Item {Name = "Elixir of the Mongoose", SellIn = 5, Quality = 7}, + new Item {Name = "Sulfuras, Hand of Ragnaros", SellIn = 0, Quality = 80}, + new Item {Name = "Sulfuras, Hand of Ragnaros", SellIn = -1, Quality = 80}, + new Item + { + Name = "Backstage passes to a TAFKAL80ETC concert", + SellIn = 15, + Quality = 20 + }, + new Item + { + Name = "Backstage passes to a TAFKAL80ETC concert", + SellIn = 10, + Quality = 49 + }, + new Item + { + Name = "Backstage passes to a TAFKAL80ETC concert", + SellIn = 5, + Quality = 49 + }, + // this conjured item does not work properly yet + new Item {Name = "Conjured Mana Cake", SellIn = 3, Quality = 6} + }; + + var app = new GildedRose(Items); + + + for (var i = 0; i < 31; i++) + { + System.Console.WriteLine("-------- day " + i + " --------"); + System.Console.WriteLine("name, sellIn, quality"); + for (var j = 0; j < Items.Count; j++) + { + System.Console.WriteLine(Items[j].Name + ", " + Items[j].SellIn + ", " + Items[j].Quality); + } + System.Console.WriteLine(""); + app.UpdateQuality(); + } + + } + + } +} diff --git a/GildedRose/python/texttest_fixture.py b/GildedRose/python/texttest_fixture.py index de921093..f867345e 100644 --- a/GildedRose/python/texttest_fixture.py +++ b/GildedRose/python/texttest_fixture.py @@ -26,4 +26,4 @@ if __name__ == "__main__": for item in items: print(item) print("") - update_quality(items) + GildedRose(items).update_quality() diff --git a/GildedRose/ruby/.rspec b/GildedRose/ruby/.rspec new file mode 100644 index 00000000..0d9a0dd8 --- /dev/null +++ b/GildedRose/ruby/.rspec @@ -0,0 +1,2 @@ +--colour +--format nested diff --git a/GildedRose/ruby/texttest_fixture.rb b/GildedRose/ruby/texttest_fixture.rb index c639c06b..b9d26c28 100644 --- a/GildedRose/ruby/texttest_fixture.rb +++ b/GildedRose/ruby/texttest_fixture.rb @@ -21,7 +21,7 @@ if ARGV.size > 0 days = ARGV[0].to_i + 1 end -gilded_rose = GildedRose.new +gilded_rose = GildedRose.new items (0...days).each do |day| puts "-------- day #{day} --------" puts "name, sellIn, quality" @@ -29,5 +29,5 @@ gilded_rose = GildedRose.new puts item end puts "" - gilded_rose.update_quality(items) + gilded_rose.update_quality end diff --git a/GildedRose/texttests/config.gr b/GildedRose/texttests/config.gr index e7b88344..e6cfd5c7 100755 --- a/GildedRose/texttests/config.gr +++ b/GildedRose/texttests/config.gr @@ -4,7 +4,7 @@ full_name:Gilded Rose Refactoring Kata default_checkout:/Users/emily/training_materials/Refactoring-Katas/GildedRose # Settings for the Java version -executable:TexttestFixture +executable:com.gildedrose.TexttestFixture interpreter:java # note you'll also need to update the file environment.gr with your classpath if you keep your classfiles somewhere unusual @@ -20,7 +20,7 @@ interpreter:java #interpreter:ruby # Settings for the C# version -#executable:${TEXTTEST_CHECKOUT}/csharp/Program.exe +#executable:${TEXTTEST_CHECKOUT}/GildedRose.exe # turn on one of these if you prefer them to notepad or emacs. [view_program] diff --git a/Yahtzee/README.md b/Yahtzee/README.md index e861ff50..8a7575fb 100644 --- a/Yahtzee/README.md +++ b/Yahtzee/README.md @@ -6,6 +6,8 @@ The other language translations have been contributed by: Python: Emily Bache +Ruby: Kim Persson and Lennart Fridén + ## Kata: Yahtzee rules The game of yahtzee is a simple dice game. Each player diff --git a/Yahtzee/ruby/test_yahtzee.rb b/Yahtzee/ruby/test_yahtzee.rb new file mode 100644 index 00000000..988c0f0d --- /dev/null +++ b/Yahtzee/ruby/test_yahtzee.rb @@ -0,0 +1,94 @@ +require_relative 'yahtzee' +require 'test/unit' + +class YahtzeeTest < Test::Unit::TestCase + def test_chance_scores_sum_of_all_dice + expected = 15 + actual = Yahtzee.chance(2,3,4,5,1) + assert expected == actual + assert 16 == Yahtzee.chance(3,3,4,5,1) + end + + def test_yahtzee_scores_50 + expected = 50 + actual = Yahtzee.yahtzee([4,4,4,4,4]) + assert expected == actual + assert 50 == Yahtzee.yahtzee([6,6,6,6,6]) + assert 0 == Yahtzee.yahtzee([6,6,6,6,3]) + end + + def test_1s + assert Yahtzee.ones(1,2,3,4,5) == 1 + assert 2 == Yahtzee.ones(1,2,1,4,5) + assert 0 == Yahtzee.ones(6,2,2,4,5) + assert 4 == Yahtzee.ones(1,2,1,1,1) + end + + def test_2s + assert Yahtzee.twos(1,2,3,2,6) == 4 + assert Yahtzee.twos(2,2,2,2,2) == 10 + end + + def test_threes + assert 6 == Yahtzee.threes(1,2,3,2,3) + assert 12 == Yahtzee.threes(2,3,3,3,3) + end + + def test_fours_test + assert 12 == Yahtzee.new(4,4,4,5,5).fours + assert 8 == Yahtzee.new(4,4,5,5,5).fours + assert 4 == Yahtzee.new(4,5,5,5,5).fours + end + + def test_fives() + assert 10 == Yahtzee.new(4,4,4,5,5).fives() + assert 15 == Yahtzee.new(4,4,5,5,5).fives() + assert 20 == Yahtzee.new(4,5,5,5,5).fives() + end + + def test_sixes_test + assert 0 == Yahtzee.new(4,4,4,5,5).sixes() + assert 6 == Yahtzee.new(4,4,6,5,5).sixes() + assert 18 == Yahtzee.new(6,5,6,6,5).sixes() + end + + def test_one_pair + assert 6 == Yahtzee.score_pair(3,4,3,5,6) + assert 10 == Yahtzee.score_pair(5,3,3,3,5) + assert 12 == Yahtzee.score_pair(5,3,6,6,5) + end + + def test_two_Pair + assert_equal 16, Yahtzee.two_pair(3,3,5,4,5) + assert_equal 0, Yahtzee.two_pair(3,3,5,5,5) + end + + def test_three_of_a_kind() + assert 9 == Yahtzee.three_of_a_kind(3,3,3,4,5) + assert 15 == Yahtzee.three_of_a_kind(5,3,5,4,5) + assert 0 == Yahtzee.three_of_a_kind(3,3,3,3,5) + end + + def test_four_of_a_knd + assert 12 == Yahtzee.four_of_a_kind(3,3,3,3,5) + assert 20 == Yahtzee.four_of_a_kind(5,5,5,4,5) + assert 0 == Yahtzee.three_of_a_kind(3,3,3,3,3) + end + + def test_smallStraight() + assert 15 == Yahtzee.smallStraight(1,2,3,4,5) + assert 15 == Yahtzee.smallStraight(2,3,4,5,1) + assert 0 == Yahtzee.smallStraight(1,2,2,4,5) + end + + def test_largeStraight + assert 20 == Yahtzee.largeStraight(6,2,3,4,5) + assert 20 == Yahtzee.largeStraight(2,3,4,5,6) + assert 0 == Yahtzee.largeStraight(1,2,2,4,5) + end + + def test_fullHouse() + assert 18 == Yahtzee.fullHouse(6,2,2,2,6) + assert 0 == Yahtzee.fullHouse(2,3,4,5,6) + end +end diff --git a/Yahtzee/ruby/yahtzee.rb b/Yahtzee/ruby/yahtzee.rb new file mode 100644 index 00000000..462b0509 --- /dev/null +++ b/Yahtzee/ruby/yahtzee.rb @@ -0,0 +1,256 @@ +class Yahtzee + def self.chance(d1, d2, d3, d4, d5) + total = 0 + total += d1 + total += d2 + total += d3 + total += d4 + total += d5 + return total + end + + def self.yahtzee(dice) + counts = [0]*(dice.length+1) + for die in dice do + counts[die-1] += 1 + end + for i in 0..counts.size do + if counts[i] == 5 + return 50 + end + end + return 0 + end + + def self.ones( d1, d2, d3, d4, d5) + sum = 0 + if (d1 == 1) + sum += 1 + end + if (d2 == 1) + sum += 1 + end + if (d3 == 1) + sum += 1 + end + if (d4 == 1) + sum += 1 + end + if (d5 == 1) + sum += 1 + end + + sum + end + + def self.twos( d1, d2, d3, d4, d5) + sum = 0 + if (d1 == 2) + sum += 2 + end + if (d2 == 2) + sum += 2 + end + if (d3 == 2) + sum += 2 + end + if (d4 == 2) + sum += 2 + end + if (d5 == 2) + sum += 2 + end + return sum + end + + def self.threes( d1, d2, d3, d4, d5) + s = 0 + if (d1 == 3) + s += 3 + end + if (d2 == 3) + s += 3 + end + if (d3 == 3) + s += 3 + end + if (d4 == 3) + s += 3 + end + if (d5 == 3) + s += 3 + end + return s + end + + def initialize(d1, d2, d3, d4, _5) + @dice = [0]*5 + @dice[0] = d1 + @dice[1] = d2 + @dice[2] = d3 + @dice[3] = d4 + @dice[4] = _5 + end + + def fours + sum = 0 + for at in Array 0..4 + if (@dice[at] == 4) + sum += 4 + end + end + return sum + end + + def fives() + s = 0 + i = 0 + for i in (Range.new(0, @dice.size)) + if (@dice[i] == 5) + s = s + 5 + end + end + s + end + + def sixes + sum = 0 + for at in 0..@dice.length + if (@dice[at] == 6) + sum = sum + 6 + end + end + return sum + end + + def self.score_pair( d1, d2, d3, d4, d5) + counts = [0]*6 + counts[d1-1] += 1 + counts[d2-1] += 1 + counts[d3-1] += 1 + counts[d4-1] += 1 + counts[d5-1] += 1 + at = 0 + (0...6).each do |at| + if (counts[6-at-1] == 2) + return (6-at)*2 + end + end + return 0 + end + + def self.two_pair( d1, d2, d3, d4, d5) + counts = [0]*6 + counts[d1-1] += 1 + counts[d2-1] += 1 + counts[d3-1] += 1 + counts[d4-1] += 1 + counts[d5-1] += 1 + n = 0 + score = 0 + for i in Array 0..5 + if (counts[6-i-1] == 2) + n = n+1 + score += (6-i) + end + end + if (n == 2) + return score * 2 + else + return 0 + end + end + + def self.four_of_a_kind( _1, _2, d3, d4, d5) + tallies = [0]*6 + tallies[_1-1] += 1 + tallies[_2-1] += 1 + tallies[d3-1] += 1 + tallies[d4-1] += 1 + tallies[d5-1] += 1 + for i in (0..6) + if (tallies[i] == 4) + return (i+1) * 4 + end + end + return 0 + end + + def self.three_of_a_kind( d1, d2, d3, d4, d5) + t = [0]*6 + t[d1-1] += 1 + t[d2-1] += 1 + t[d3-1] += 1 + t[d4-1] += 1 + t[d5-1] += 1 + for i in [0,1,2,3,4,5] + if (t[i] == 3) + return (i+1) * 3 + end + end + 0 + end + + def self.smallStraight( d1, d2, d3, d4, d5) + tallies = [0]*6 + tallies[d1-1] += 1 + tallies[d2-1] += 1 + tallies[d3-1] += 1 + tallies[d4-1] += 1 + tallies[d5-1] += 1 + (tallies[0] == 1 and + tallies[1] == 1 and + tallies[2] == 1 and + tallies[3] == 1 and + tallies[4] == 1) ? 15 : 0 + end + + def self.largeStraight( d1, d2, d3, d4, d5) + tallies = [0]*6 + tallies[d1-1] += 1 + tallies[d2-1] += 1 + tallies[d3-1] += 1 + tallies[d4-1] += 1 + tallies[d5-1] += 1 + if (tallies[1] == 1 and tallies[2] == 1 and tallies[3] == 1 and tallies[4] == 1 and tallies[5] == 1) + return 20 + end + return 0 + end + + def self.fullHouse( d1, d2, d3, d4, d5) + tallies = [] + _2 = false + i = 0 + _2_at = 0 + _3 = false + _3_at = 0 + + tallies = [0]*6 + tallies[d1-1] += 1 + tallies[d2-1] += 1 + tallies[d3-1] += 1 + tallies[d4-1] += 1 + tallies[d5-1] += 1 + + for i in Array 0..5 + if (tallies[i] == 2) + _2 = true + _2_at = i+1 + end + end + + for i in Array 0..5 + if (tallies[i] == 3) + _3 = true + _3_at = i+1 + end + end + + if (_2 and _3) + return _2_at * 2 + _3_at * 3 + else + return 0 + end + end +end