From a2dc514955804336f0ebbe0839ac5e9617f9c287 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 28 Jul 2022 22:09:57 +1000 Subject: [PATCH 1/4] Add text resources --- 34_Digits/csharp/Digits.csproj | 8 ++++ .../csharp/Resources/ForInstructions.txt | 1 + 34_Digits/csharp/Resources/Headings.txt | 1 + 34_Digits/csharp/Resources/IWin.txt | 3 ++ 34_Digits/csharp/Resources/Instructions.txt | 11 +++++ 34_Digits/csharp/Resources/Introduction.txt | 6 +++ 34_Digits/csharp/Resources/ItsATie.txt | 3 ++ 34_Digits/csharp/Resources/Resource.cs | 44 +++++++++++++++++++ 34_Digits/csharp/Resources/TenNumbers.txt | 1 + 34_Digits/csharp/Resources/Thanks.txt | 2 + 34_Digits/csharp/Resources/TryAgain.txt | 2 + 34_Digits/csharp/Resources/WantToTryAgain.txt | 1 + 34_Digits/csharp/Resources/YouWin.txt | 3 ++ 13 files changed, 86 insertions(+) create mode 100644 34_Digits/csharp/Resources/ForInstructions.txt create mode 100644 34_Digits/csharp/Resources/Headings.txt create mode 100644 34_Digits/csharp/Resources/IWin.txt create mode 100644 34_Digits/csharp/Resources/Instructions.txt create mode 100644 34_Digits/csharp/Resources/Introduction.txt create mode 100644 34_Digits/csharp/Resources/ItsATie.txt create mode 100644 34_Digits/csharp/Resources/Resource.cs create mode 100644 34_Digits/csharp/Resources/TenNumbers.txt create mode 100644 34_Digits/csharp/Resources/Thanks.txt create mode 100644 34_Digits/csharp/Resources/TryAgain.txt create mode 100644 34_Digits/csharp/Resources/WantToTryAgain.txt create mode 100644 34_Digits/csharp/Resources/YouWin.txt diff --git a/34_Digits/csharp/Digits.csproj b/34_Digits/csharp/Digits.csproj index d3fe4757..3870320c 100644 --- a/34_Digits/csharp/Digits.csproj +++ b/34_Digits/csharp/Digits.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/34_Digits/csharp/Resources/ForInstructions.txt b/34_Digits/csharp/Resources/ForInstructions.txt new file mode 100644 index 00000000..1c16d5f4 --- /dev/null +++ b/34_Digits/csharp/Resources/ForInstructions.txt @@ -0,0 +1 @@ +For instructions, type '1', else type '0' \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Headings.txt b/34_Digits/csharp/Resources/Headings.txt new file mode 100644 index 00000000..b9ece8ff --- /dev/null +++ b/34_Digits/csharp/Resources/Headings.txt @@ -0,0 +1 @@ +My guess Your no. Result No. right diff --git a/34_Digits/csharp/Resources/IWin.txt b/34_Digits/csharp/Resources/IWin.txt new file mode 100644 index 00000000..d810c60f --- /dev/null +++ b/34_Digits/csharp/Resources/IWin.txt @@ -0,0 +1,3 @@ +I guessed more than 1/3 of your numbers. +I win. + diff --git a/34_Digits/csharp/Resources/Instructions.txt b/34_Digits/csharp/Resources/Instructions.txt new file mode 100644 index 00000000..f9ff2a16 --- /dev/null +++ b/34_Digits/csharp/Resources/Instructions.txt @@ -0,0 +1,11 @@ + +Please take a piece of paper and write down +the digits '0', '1', or '2' thirty times at random. +Arrange them in three lines of ten digits each. +I will ask for then ten at a time. +I will always guess them first and then look at your +next number to see if I was right. By pure luck, +I ought to be right ten times. But I hope to do better +than that ***** + + diff --git a/34_Digits/csharp/Resources/Introduction.txt b/34_Digits/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..e4d2d93e --- /dev/null +++ b/34_Digits/csharp/Resources/Introduction.txt @@ -0,0 +1,6 @@ + Digits + Creative Computing Morristown, New Jersey + + + +This is a game of guessing. diff --git a/34_Digits/csharp/Resources/ItsATie.txt b/34_Digits/csharp/Resources/ItsATie.txt new file mode 100644 index 00000000..e80525f8 --- /dev/null +++ b/34_Digits/csharp/Resources/ItsATie.txt @@ -0,0 +1,3 @@ +I guessed exactly 1/3 of your numbers. +It's a tie game. + diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs new file mode 100644 index 00000000..7252c817 --- /dev/null +++ b/34_Digits/csharp/Resources/Resource.cs @@ -0,0 +1,44 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Chomp.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream Instructions => GetStream(); + public static Stream TryAgain => GetStream(); + public static Stream ItsATie => GetStream(); + public static Stream IWin => GetStream(); + public static Stream YouWin => GetStream(); + public static Stream Thanks => GetStream(); + public static Stream Headings => GetStream(); + } + + internal static class Prompts + { + public static string ForInstructions => GetString(); + public static string TenNumbers => GetString(); + public static string WantToTryAgain => GetString(); + } + + internal static class Strings + { + public static string TooManyColumns => GetString(); + public static string TooManyRows => GetString(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/34_Digits/csharp/Resources/TenNumbers.txt b/34_Digits/csharp/Resources/TenNumbers.txt new file mode 100644 index 00000000..5286066b --- /dev/null +++ b/34_Digits/csharp/Resources/TenNumbers.txt @@ -0,0 +1 @@ +Ten numbers, please \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Thanks.txt b/34_Digits/csharp/Resources/Thanks.txt new file mode 100644 index 00000000..15d42e1b --- /dev/null +++ b/34_Digits/csharp/Resources/Thanks.txt @@ -0,0 +1,2 @@ + +Thanks for the game diff --git a/34_Digits/csharp/Resources/TryAgain.txt b/34_Digits/csharp/Resources/TryAgain.txt new file mode 100644 index 00000000..74bdca68 --- /dev/null +++ b/34_Digits/csharp/Resources/TryAgain.txt @@ -0,0 +1,2 @@ +Only use the digits '0', '1', or '2'. +Let's try again. diff --git a/34_Digits/csharp/Resources/WantToTryAgain.txt b/34_Digits/csharp/Resources/WantToTryAgain.txt new file mode 100644 index 00000000..38f4509d --- /dev/null +++ b/34_Digits/csharp/Resources/WantToTryAgain.txt @@ -0,0 +1 @@ +Do you want to try again (1 for yes, 0 for no) \ No newline at end of file diff --git a/34_Digits/csharp/Resources/YouWin.txt b/34_Digits/csharp/Resources/YouWin.txt new file mode 100644 index 00000000..120997d4 --- /dev/null +++ b/34_Digits/csharp/Resources/YouWin.txt @@ -0,0 +1,3 @@ +I guessed less than 1/3 of your numbers. +You beat me. Congratulations ***** + From aedfd73e8c5f7a1a85d80391f49500708aa4555c Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 30 Jul 2022 16:19:50 +1000 Subject: [PATCH 2/4] Add main game loop --- 34_Digits/csharp/Game.cs | 36 ++++++++++++++++++++++++++ 34_Digits/csharp/Program.cs | 6 +++++ 34_Digits/csharp/Resources/Resource.cs | 8 +----- 3 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 34_Digits/csharp/Game.cs create mode 100644 34_Digits/csharp/Program.cs diff --git a/34_Digits/csharp/Game.cs b/34_Digits/csharp/Game.cs new file mode 100644 index 00000000..2ddab01d --- /dev/null +++ b/34_Digits/csharp/Game.cs @@ -0,0 +1,36 @@ +namespace Digits +{ + internal class Game + { + private readonly IReadWrite _io; + private readonly IRandom _random; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _random = random; + } + + internal void Play() + { + _io.Write(Streams.Introduction); + + if (_io.ReadNumber(Prompts.ForInstructions) != 0) + { + _io.Write(Streams.Instructions); + } + + do + { + PlayOne(); + } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1); + + _io.Write(Streams.Thanks); + } + + private void PlayOne() + { + + } + } +} \ No newline at end of file diff --git a/34_Digits/csharp/Program.cs b/34_Digits/csharp/Program.cs new file mode 100644 index 00000000..a427b3c8 --- /dev/null +++ b/34_Digits/csharp/Program.cs @@ -0,0 +1,6 @@ +global using Digits; +global using Games.Common.IO; +global using Games.Common.Randomness; +global using static Digits.Resources.Resource; + +new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs index 7252c817..0a939802 100644 --- a/34_Digits/csharp/Resources/Resource.cs +++ b/34_Digits/csharp/Resources/Resource.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; -namespace Chomp.Resources; +namespace Digits.Resources; internal static class Resource { @@ -24,12 +24,6 @@ internal static class Resource public static string WantToTryAgain => GetString(); } - internal static class Strings - { - public static string TooManyColumns => GetString(); - public static string TooManyRows => GetString(); - } - private static string GetString([CallerMemberName] string? name = null) { using var stream = GetStream(name); From 572b9b3a695d8a893542138f3c62773fba978b9b Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 3 Aug 2022 08:40:05 +1000 Subject: [PATCH 3/4] Complete game --- 34_Digits/csharp/Game.cs | 110 ++++++++++++++------- 34_Digits/csharp/Guesser.cs | 52 ++++++++++ 34_Digits/csharp/IOExtensions.cs | 20 ++++ 34_Digits/csharp/Program.cs | 2 +- 34_Digits/csharp/Resources/GuessResult.txt | 1 + 34_Digits/csharp/Resources/Headings.txt | 2 + 34_Digits/csharp/Resources/Resource.cs | 5 + 34_Digits/csharp/Resources/TenNumbers.txt | 1 + 8 files changed, 159 insertions(+), 34 deletions(-) create mode 100644 34_Digits/csharp/Guesser.cs create mode 100644 34_Digits/csharp/IOExtensions.cs create mode 100644 34_Digits/csharp/Resources/GuessResult.txt diff --git a/34_Digits/csharp/Game.cs b/34_Digits/csharp/Game.cs index 2ddab01d..19f225b3 100644 --- a/34_Digits/csharp/Game.cs +++ b/34_Digits/csharp/Game.cs @@ -1,36 +1,80 @@ -namespace Digits +namespace Digits; + +internal class GameSeries { - internal class Game + private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly(); + + private readonly IReadWrite _io; + private readonly IRandom _random; + + public GameSeries(IReadWrite io, IRandom random) { - private readonly IReadWrite _io; - private readonly IRandom _random; - - public Game(IReadWrite io, IRandom random) - { - _io = io; - _random = random; - } - - internal void Play() - { - _io.Write(Streams.Introduction); - - if (_io.ReadNumber(Prompts.ForInstructions) != 0) - { - _io.Write(Streams.Instructions); - } - - do - { - PlayOne(); - } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1); - - _io.Write(Streams.Thanks); - } - - private void PlayOne() - { - - } + _io = io; + _random = random; } -} \ No newline at end of file + + internal void Play() + { + _io.Write(Streams.Introduction); + + if (_io.ReadNumber(Prompts.ForInstructions) != 0) + { + _io.Write(Streams.Instructions); + } + + do + { + new Game(_io, _random).Play(); + } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1); + + _io.Write(Streams.Thanks); + } +} + +internal class Game +{ + private readonly IReadWrite _io; + private readonly Guesser _guesser; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _guesser = new Guesser(random); + } + + public void Play() + { + var correctGuesses = 0; + + for (int round = 0; round < 3; round++) + { + var digits = _io.Read10Digits(Prompts.TenNumbers, Streams.TryAgain); + + correctGuesses = GuessDigits(digits, correctGuesses); + } + + _io.Write(correctGuesses switch + { + < 10 => Streams.YouWin, + 10 => Streams.ItsATie, + > 10 => Streams.IWin + }); + } + + private int GuessDigits(IEnumerable digits, int correctGuesses) + { + _io.Write(Streams.Headings); + + foreach (var digit in digits) + { + var guess = _guesser.GuessNextDigit(); + if (guess == digit) { correctGuesses++; } + + _io.WriteLine(Formats.GuessResult, guess, digit, guess == digit ? "Right" : "Wrong", correctGuesses); + + _guesser.ObserveActualDigit(digit); + } + + return correctGuesses; + } +} diff --git a/34_Digits/csharp/Guesser.cs b/34_Digits/csharp/Guesser.cs new file mode 100644 index 00000000..debeed18 --- /dev/null +++ b/34_Digits/csharp/Guesser.cs @@ -0,0 +1,52 @@ +namespace Digits; + +internal class Guesser +{ + private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly(); + private readonly int[][,] _matrices = new[] { new int[3, 3], new int[9, 3], new int[27, 3] }; + private readonly int[] _indices = new[] { 2, 8, 26 }; + private readonly IRandom _random; + + public Guesser(IRandom random) + { + _random = random; + + for (int j = 0; j < 3; j++) + { + for (int i = 0; i < 3; i++) { _matrices[0][i, j] = 9; } + for (int i = 0; i < 9; i++) { _matrices[1][i, j] = i == 4 * j ? 2 : 3; } + for (int i = 0; i < 27; i++) { _matrices[2][i, j] = 1; } + } + } + + public int GuessNextDigit() + { + var currentSum = 0; + var guess = 0; + + for (int j = 0; j < 3; j++) + { + var sum = Enumerable.Range(0, 3).Aggregate((s, i) => s + GetWeightedValue(i, j)); + if (sum > currentSum || _random.NextFloat() >= 0.5) + { + currentSum = sum; + guess = j; + } + } + + return guess; + } + + public void ObserveActualDigit(int digit) + { + for (int i = 0; i < 3; i++) + { + _matrices[i][_indices[i], digit]++; + } + _indices[2] = _indices[2] % 9 * 3 + digit; + _indices[1] = _indices[2] % 9; + _indices[0] = digit; + } + + private int GetWeightedValue(int matrix, int row) => _weights[matrix] * _matrices[matrix][_indices[matrix], row]; +} \ No newline at end of file diff --git a/34_Digits/csharp/IOExtensions.cs b/34_Digits/csharp/IOExtensions.cs new file mode 100644 index 00000000..cd6af7ad --- /dev/null +++ b/34_Digits/csharp/IOExtensions.cs @@ -0,0 +1,20 @@ +namespace Digits; + +internal static class IOExtensions +{ + internal static IEnumerable Read10Digits(this IReadWrite io, string prompt, Stream retryText) + { + while (true) + { + var numbers = new float[10]; + io.ReadNumbers(prompt, numbers); + + if (numbers.All(n => n == 0 || n == 1 || n == 2)) + { + return numbers.Select(n => (int)n); + } + + io.Write(retryText); + } + } +} \ No newline at end of file diff --git a/34_Digits/csharp/Program.cs b/34_Digits/csharp/Program.cs index a427b3c8..1b5dd2e0 100644 --- a/34_Digits/csharp/Program.cs +++ b/34_Digits/csharp/Program.cs @@ -3,4 +3,4 @@ global using Games.Common.IO; global using Games.Common.Randomness; global using static Digits.Resources.Resource; -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); \ No newline at end of file +new GameSeries(new ConsoleIO(), new RandomNumberGenerator()).Play(); \ No newline at end of file diff --git a/34_Digits/csharp/Resources/GuessResult.txt b/34_Digits/csharp/Resources/GuessResult.txt new file mode 100644 index 00000000..4e233e03 --- /dev/null +++ b/34_Digits/csharp/Resources/GuessResult.txt @@ -0,0 +1 @@ + {0} {1} {2} {3} \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Headings.txt b/34_Digits/csharp/Resources/Headings.txt index b9ece8ff..8289cdf6 100644 --- a/34_Digits/csharp/Resources/Headings.txt +++ b/34_Digits/csharp/Resources/Headings.txt @@ -1 +1,3 @@ + My guess Your no. Result No. right + diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs index 0a939802..2e935955 100644 --- a/34_Digits/csharp/Resources/Resource.cs +++ b/34_Digits/csharp/Resources/Resource.cs @@ -24,6 +24,11 @@ internal static class Resource public static string WantToTryAgain => GetString(); } + internal static class Formats + { + public static string GuessResult => GetString(); + } + private static string GetString([CallerMemberName] string? name = null) { using var stream = GetStream(name); diff --git a/34_Digits/csharp/Resources/TenNumbers.txt b/34_Digits/csharp/Resources/TenNumbers.txt index 5286066b..ad03893a 100644 --- a/34_Digits/csharp/Resources/TenNumbers.txt +++ b/34_Digits/csharp/Resources/TenNumbers.txt @@ -1 +1,2 @@ + Ten numbers, please \ No newline at end of file From b67a5d438c2794916e40690a86945b145b693767 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 3 Aug 2022 23:34:02 +1000 Subject: [PATCH 4/4] Add Memory and Matrix --- 34_Digits/csharp/Guesser.cs | 32 +++++--------------------- 34_Digits/csharp/Matrix.cs | 27 ++++++++++++++++++++++ 34_Digits/csharp/Memory.cs | 30 ++++++++++++++++++++++++ 34_Digits/csharp/Resources/IWin.txt | 1 + 34_Digits/csharp/Resources/ItsATie.txt | 1 + 34_Digits/csharp/Resources/YouWin.txt | 1 + 6 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 34_Digits/csharp/Matrix.cs create mode 100644 34_Digits/csharp/Memory.cs diff --git a/34_Digits/csharp/Guesser.cs b/34_Digits/csharp/Guesser.cs index debeed18..9cda59e9 100644 --- a/34_Digits/csharp/Guesser.cs +++ b/34_Digits/csharp/Guesser.cs @@ -2,21 +2,12 @@ namespace Digits; internal class Guesser { - private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly(); - private readonly int[][,] _matrices = new[] { new int[3, 3], new int[9, 3], new int[27, 3] }; - private readonly int[] _indices = new[] { 2, 8, 26 }; + private readonly Memory _matrices = new(); private readonly IRandom _random; public Guesser(IRandom random) { _random = random; - - for (int j = 0; j < 3; j++) - { - for (int i = 0; i < 3; i++) { _matrices[0][i, j] = 9; } - for (int i = 0; i < 9; i++) { _matrices[1][i, j] = i == 4 * j ? 2 : 3; } - for (int i = 0; i < 27; i++) { _matrices[2][i, j] = 1; } - } } public int GuessNextDigit() @@ -24,29 +15,18 @@ internal class Guesser var currentSum = 0; var guess = 0; - for (int j = 0; j < 3; j++) + for (int i = 0; i < 3; i++) { - var sum = Enumerable.Range(0, 3).Aggregate((s, i) => s + GetWeightedValue(i, j)); + var sum = _matrices.GetWeightedSum(i); if (sum > currentSum || _random.NextFloat() >= 0.5) { currentSum = sum; - guess = j; + guess = i; } } return guess; } - public void ObserveActualDigit(int digit) - { - for (int i = 0; i < 3; i++) - { - _matrices[i][_indices[i], digit]++; - } - _indices[2] = _indices[2] % 9 * 3 + digit; - _indices[1] = _indices[2] % 9; - _indices[0] = digit; - } - - private int GetWeightedValue(int matrix, int row) => _weights[matrix] * _matrices[matrix][_indices[matrix], row]; -} \ No newline at end of file + public void ObserveActualDigit(int digit) => _matrices.ObserveDigit(digit); +} diff --git a/34_Digits/csharp/Matrix.cs b/34_Digits/csharp/Matrix.cs new file mode 100644 index 00000000..c07b4553 --- /dev/null +++ b/34_Digits/csharp/Matrix.cs @@ -0,0 +1,27 @@ +namespace Digits; + +internal class Matrix +{ + private readonly int _weight; + private readonly int[,] _values; + + public Matrix(int width, int weight, Func seedFactory) + { + _weight = weight; + _values = new int[width, 3]; + + for (int i = 0; i < width; i++) + for (int j = 0; j < 3; j++) + { + _values[i, j] = seedFactory.Invoke(i, j); + } + + Index = width - 1; + } + + public int Index { get; set; } + + public int GetWeightedValue(int row) => _weight * _values[Index, row]; + + public int IncrementValue(int row) => _values[Index, row]++; +} \ No newline at end of file diff --git a/34_Digits/csharp/Memory.cs b/34_Digits/csharp/Memory.cs new file mode 100644 index 00000000..a3023351 --- /dev/null +++ b/34_Digits/csharp/Memory.cs @@ -0,0 +1,30 @@ +namespace Digits; + +public class Memory +{ + private readonly Matrix[] _matrices; + + public Memory() + { + _matrices = new[] + { + new Matrix(27, 3, (_, _) => 1), + new Matrix(9, 1, (i, j) => i == 4 * j ? 2 : 3), + new Matrix(3, 0, (_, _) => 9) + }; + } + + public int GetWeightedSum(int row) => _matrices.Select(m => m.GetWeightedValue(row)).Sum(); + + public void ObserveDigit(int digit) + { + for (int i = 0; i < 3; i++) + { + _matrices[i].IncrementValue(digit); + } + + _matrices[0].Index = _matrices[0].Index % 9 * 3 + digit; + _matrices[1].Index = _matrices[0].Index % 9; + _matrices[2].Index = digit; + } +} \ No newline at end of file diff --git a/34_Digits/csharp/Resources/IWin.txt b/34_Digits/csharp/Resources/IWin.txt index d810c60f..491f69cf 100644 --- a/34_Digits/csharp/Resources/IWin.txt +++ b/34_Digits/csharp/Resources/IWin.txt @@ -1,3 +1,4 @@ + I guessed more than 1/3 of your numbers. I win. diff --git a/34_Digits/csharp/Resources/ItsATie.txt b/34_Digits/csharp/Resources/ItsATie.txt index e80525f8..0e92fbf6 100644 --- a/34_Digits/csharp/Resources/ItsATie.txt +++ b/34_Digits/csharp/Resources/ItsATie.txt @@ -1,3 +1,4 @@ + I guessed exactly 1/3 of your numbers. It's a tie game. diff --git a/34_Digits/csharp/Resources/YouWin.txt b/34_Digits/csharp/Resources/YouWin.txt index 120997d4..87b26b38 100644 --- a/34_Digits/csharp/Resources/YouWin.txt +++ b/34_Digits/csharp/Resources/YouWin.txt @@ -1,3 +1,4 @@ + I guessed less than 1/3 of your numbers. You beat me. Congratulations *****