mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2025-12-12 12:22:12 +00:00
Merge branch 'master' of github.com:emilybache/Refactoring-Katas
This commit is contained in:
commit
d3c89db5c9
@ -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.
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
package com.gildedrose;
|
||||
class GildedRose {
|
||||
Item[] items;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
package com.gildedrose;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -1,3 +1,4 @@
|
||||
package com.gildedrose;
|
||||
public class Item {
|
||||
|
||||
public String name;
|
||||
@ -1,3 +1,4 @@
|
||||
package com.gildedrose;
|
||||
|
||||
public class TexttestFixture {
|
||||
public static void main(String[] args) {
|
||||
@ -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
|
||||
|
||||
28
GildedRose/csharp/ApprovalTest.cs
Normal file
28
GildedRose/csharp/ApprovalTest.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
100
GildedRose/csharp/GildedRose.cs
Normal file
100
GildedRose/csharp/GildedRose.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GildedRose
|
||||
{
|
||||
class GildedRose
|
||||
{
|
||||
IList<Item> Items;
|
||||
public GildedRose(IList<Item> 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; }
|
||||
}
|
||||
|
||||
}
|
||||
19
GildedRose/csharp/GildedRoseTest.cs
Normal file
19
GildedRose/csharp/GildedRoseTest.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GildedRose
|
||||
{
|
||||
[TestFixture()]
|
||||
public class GildedRoseTest
|
||||
{
|
||||
[Test()]
|
||||
public void foo() {
|
||||
IList<Item> Items = new List<Item> { new Item{Name = "foo", SellIn = 0, Quality = 0} };
|
||||
GildedRose app = new GildedRose(Items);
|
||||
app.UpdateQuality();
|
||||
Assert.AreEqual("fixme", Items[0].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,147 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GildedRose.Console
|
||||
{
|
||||
class Program
|
||||
{
|
||||
IList<Item> Items;
|
||||
static void Main(string[] args)
|
||||
{
|
||||
System.Console.WriteLine("OMGHAI!");
|
||||
|
||||
var app = new Program()
|
||||
{
|
||||
Items = new List<Item>
|
||||
{
|
||||
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; }
|
||||
}
|
||||
|
||||
}
|
||||
58
GildedRose/csharp/TextTestFixture.cs
Normal file
58
GildedRose/csharp/TextTestFixture.cs
Normal file
@ -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<Item> Items = new List<Item>{
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -26,4 +26,4 @@ if __name__ == "__main__":
|
||||
for item in items:
|
||||
print(item)
|
||||
print("")
|
||||
update_quality(items)
|
||||
GildedRose(items).update_quality()
|
||||
|
||||
2
GildedRose/ruby/.rspec
Normal file
2
GildedRose/ruby/.rspec
Normal file
@ -0,0 +1,2 @@
|
||||
--colour
|
||||
--format nested
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
|
||||
94
Yahtzee/ruby/test_yahtzee.rb
Normal file
94
Yahtzee/ruby/test_yahtzee.rb
Normal file
@ -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
|
||||
256
Yahtzee/ruby/yahtzee.rb
Normal file
256
Yahtzee/ruby/yahtzee.rb
Normal file
@ -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
|
||||
Loading…
Reference in New Issue
Block a user