For loop not working - function only getting called once - c#

I'm having some issues with my for loop. I've tried placing it in different areas and still, no luck. I'm working on a project that randomly changes the opacity of a rectangle (I have red, yellow, blue, and green). I got the project working so that it selects one color, raises opacity, waits, and then lowers opacity. However, I would like to repeat this and the loop will not.
Here is my code:
private int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
public void Start_Tapped_1(object sender, TappedRoutedEventArgs e)
{
loopthegame(5);
}
public void loopthegame(int amount)
{
for (int i = 0; i < amount; i++) {
startgame();
}
}
public async void startgame()
{
int randomcolor = RandomNumber(1, 8);
switch (randomcolor)
{
case 1:
Blue.Opacity = 1;
break;
case 2:
Red.Opacity = 1;
break;
case 3:
Yellow.Opacity = 1;
break;
case 4:
Green.Opacity = 1;
break;
case 5:
Blue.Opacity = 1;
break;
case 6:
Red.Opacity = 1;
break;
case 7:
Yellow.Opacity = 1;
break;
case 8:
Green.Opacity = 1;
break;
}
await Task.Delay(1000);
Blue.Opacity = 0.25;
Red.Opacity = 0.25;
Yellow.Opacity = 0.25;
Green.Opacity = 0.25;
}

It seems your async should be slightly updated:
public void loopthegame(int amount)
{
for (int i = 0; i < amount; i++) {
Task<int> t = startgame();
await t;
}
}
//...
public async Task<int> startgame()
{
int randomcolor = RandomNumber(1, 8);
switch (randomcolor)
{
case 1:
Blue.Opacity = 1;
break;
//...
case 8:
Green.Opacity = 1;
break;
}
await Task.Delay(1000);
Blue.Opacity = 0.25;
Red.Opacity = 0.25;
Yellow.Opacity = 0.25;
Green.Opacity = 0.25;
return randomcolor;
}

Well you need to do your async right (a slight modification):
public async void loopthegame(int amount)
{
for (int i = 0; i < amount; i++)
{
// this
await startgame();
}
}
Also:
public async Task startgame()
{
//...
}

Your problem is actually in your random number generator. When you create a random number generator with no seed (new Random()), it uses time as the seed. This runs fast enough that you're using the same seed every time, so RandomNumber returns the same number every time. Instead of creating a new Random every time, you should have one Random that you use multiple times. Create one in your constructor/main method, and use it repeatedly in your RandomNumber method.
This is easily tested with this bit of code:
for (int i = 0; i < 5; i++)
{
Random random = new Random();
Console.WriteLine(random.Next(1, 8));
}
Try it out, it will print the same value five times.

Related

c# - write a single row from a 2d array every second

I'm working on a C# console app. The "app" is a poor mans matrix (ie. 1 and 0 fall down the screen).
I've managed to make two 2d arrays, one for int and one for string. The int array is filled by RNG, and those numbers are then converted into the string array.
What I would like to achive, is to print each row from the string array every second (ElapsedEventArgs).
What I'm thinking (but isn't working) is something like this...
static void OnTimedEvent(object source, ElapsedEventArgs e)
{
if (_countDown-- <= 0)
{
Console.BackgroundColor = ConsoleColor.White;
Console.Clear();
aTimer.Enabled = false;
}
else
{
PrintSingleLine();
}
}
static void PrintSingleLine() // this should write a single line every second
{
for (int i = 0; i <=pnms.GetLength(0) - 1; i++)
{
foreach(string str in pnms)
{
Console.Write(str);
}
}
}
//if it helps, this is how you write the whole array
static void PrintArray()
{
for (int i = 0; i <= pnms.GetLength(0) - 1; i++)
{
for (int j = 0; j <= pnms.GetLength(1) - 1; j++)
{
Console.Write(nms[i, j]);
}
}
}
If I can provide any additional information, please let me know.
Thank you.
Edit 1:
So, since nothing was showing on the console, I decided to do it manually (one line per Console.ReadLine();. I figured out that i forgot to initalize the arrays (duh), and this is the code that prints the current line. It overwrites the previous one, but hey, it's something...
public static int col = 0;
static void PrintSingleLine()
{
for (int i = col; i <= pnms.GetLength(0) - 1;)
{
for (int j = 0; j <= pnms.GetLength(1) - 1; j++)
{
Console.Write(pnms[col, j]);
}
break;
}
col =+ 1;
}
Thanks to:
https://learn.microsoft.com/en-us/dotnet/api/system.timers.timer.elapsed?view=netcore-3.1
https://www.c-sharpcorner.com/article/generating-random-number-and-string-in-C-Sharp/
Not sure if this is what you're looking for, had some time to spare. This is the result. Good luck!
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Timers;
namespace PoorMatrix
{
class Program
{
private static Timer aTimer;
static void Main(string[] args)
{
aTimer = new System.Timers.Timer();
aTimer.Interval = 1000;
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
// Have the timer fire repeated events (true is the default)
aTimer.AutoReset = true;
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;
Console.Clear();
// Start the timer
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program at any time... ");
Console.ReadLine();
}
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
GenerateRandomChars(100).ForEach(i => Console.Write("{0}\t", i));
}
private static List<string> GenerateRandomChars(int paramCharAmount)
{
List<string> tempChars = new List<string>();
for (int i = 0; i < paramCharAmount; i++)
{
int LetterNumberOrEmpty = RandomNumber(0, 100);
switch (LetterNumberOrEmpty)
{
case int n when n < 41:
tempChars.Add(RandomNumber(0, 1).ToString());
break;
case int n when n < 81:
tempChars.Add(RandomLetter(RandomBool()));
break;
case int n when n < 101:
tempChars.Add(" ");
break;
default:
break;
}
}
return tempChars;
}
private static bool RandomBool()
{
return new Random().NextDouble() >= 0.5;
}
public static int RandomNumber(int paramMin, int paramMax)
{
return new Random().Next(paramMin, paramMax);
}
public static string RandomLetter(bool paramIsLowerCase = false)
{
// Unicode/ASCII Letters are divided into two blocks
// (Letters 65–90 / 97–122):
// The first group containing the uppercase letters and
// the second group containing the lowercase.
// char is a single Unicode character
char offset = paramIsLowerCase ? 'a' : 'A';
const int lettersOffset = 26; // A...Z or a..z: length=26
var #char = (char)new Random().Next(offset, offset + lettersOffset);
return paramIsLowerCase ? #char.ToString().ToLower() : #char.ToString();
}
}
}

Apple goes outside box, and a # is being written at the far right. Why?

I really don't know how to phrase my title, help me out.
I am having an issue with a game I am making. The game's objective is to eat an apple that appears on the map for points. When you eat it, another apple appears in a random location inside the little box.
As you see the apple goes out of the bounds. But it doesn't always happen on the first time I get to it. Also, there is a # at the very far right for some reason.
Here is the code:
The drawing happens in the Draw() method, so you should look at that first.
using System;
public class MainClass
{
public const int WIDTH = 20, HEIGHT = 20;
public static int Points, X, Y, FruitX, FruitY;
public static bool GameOver = false;
public static string Direction;
public static Random Rand = new Random();
public static void Start()
{
Console.Clear();
GameOver = false;
Direction = "Stop";
X = WIDTH/2;
Y = HEIGHT/2;
FruitX = Rand.Next(100)%WIDTH/2;
FruitY = Rand.Next(100)%HEIGHT/2;
}
public static void Draw()
{
Console.Clear();
for (int i = 0; i < WIDTH; i++)
{
Console.Write("# ");
}
for (int i = 0; i < HEIGHT - 1; i++)
{
for (int j = 0; j < WIDTH; j++)
{
Console.Write(j == 0 ? "# " : " ");
if (j == WIDTH - 1)
{
Console.Write("# ");
}
if (i == Y && j == X)
{
Console.Write("O");
}
else if (i == FruitY && j == FruitX)
{
Console.Write("🍎");
}
else
{
Console.Write(" ");
}
}
Console.WriteLine();
}
for (int i = 0; i < WIDTH + 1; i++)
{
Console.Write("# ");
}
Console.WriteLine($"\nPoints: {Points}");
}
public static void InputHandler()
{
ConsoleKeyInfo UserInput = Console.ReadKey();
switch (UserInput.KeyChar)
{
case 'w':
Direction = "Up";
break;
case 'a':
Direction = "Left";
break;
case 's':
Direction = "Down";
break;
case 'd':
Direction = "Right";
break;
case 'x':
GameOver = true;
break;
default:
break;
}
}
public static void GameHandler()
{
switch (Direction)
{
case "Up":
Y--;
break;
case "Down":
Y++;
break;
case "Left":
X--;
break;
case "Right":
X++;
break;
default:
break;
}
GameOver = X > WIDTH || X < 0 || Y < 0 || Y > HEIGHT;
if (X == FruitX && Y == FruitY)
{
Points += 10;
FruitX = Rand.Next(100)%WIDTH/2;
FruitY = Rand.Next(100)%HEIGHT/2;
}
}
public static void Main(string[] args)
{
Start();
while (!GameOver)
{
Draw();
InputHandler();
GameHandler();
}
Console.Clear();
}
}

Turtle Graphics - Process terminated due to StackOverflowException

I am trying to prepare a Turtle graphics solution in C#. Everything is working fine but it ends in Process Terminated due to StackOverflowException. I checked this
and
this
where the issue is of getter setter or infinite loop. But I dont have any of this condition in my code. I am a newbie in C#.
Below is my code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TurtleGraphics
{
class Program
{/**
* Directions: 0 right, 1 down, 2 left, 3 up
*/
private static short direction = 0;
private static bool penDown;
private static int turtleX = 0, turtleY = 0;
private static int[,] floor = new int[20, 20];
public static void Main(String[] args)
{
initFloor(floor);
//Scanner in = new Scanner(System.in);
printMenu();
int nextCommand = int.Parse(Console.ReadLine());
while (nextCommand != 9)
{
switch (nextCommand)
{
case 1:
penDown = false;
break;
case 2:
penDown = true;
break;
case 3:
direction++;
break;
case 4:
direction--;
break;
case 5:
Console.WriteLine("How many steps do you want to move?");
int move = int.Parse(Console.ReadLine());
if (move <= 10)
while (--move != 0)
Moves();
break;
case 6:
printArray();
break;
default:
Console.WriteLine("Unknow command, please try again:\n");
break;
}
Moves();
Console.WriteLine("What's next?");
nextCommand = int.Parse(Console.ReadLine());
}
}
private static void initFloor(int[,] floor)
{
for (int i = 0; i < floor.GetLength(0); i++)
{
for (int j = 0; j < floor.GetLength(1); j++)
{
floor[i,j] = 0;
}
}
}
private static void printMenu()
{
Console.WriteLine("Commands List:\n\n\t1 Pen up\n"
+ "\t2 Pen down\n"
+ "\t3 Turn right\n"
+ "\t4 Turn left\n"
+ "\t5 to 10 Move forward 10 spaces (replace 10 for a different number of spaces)\n"
+ "\t6 Display the 20-by-20 array\n"
+ "\t9 End of data (sentinel)Please enter a command number:\n");
}
private static void printArray()
{
for (int i = 0; i < floor.GetLength(0); i++)
{
for (int j = 0; j < floor.GetLength(1); j++)
{
// Console.WriteLine(floor[i, j]);
// Console.WriteLine(" ");
if (floor[i, j] == 0)
Console.Write(".");
else if (floor[i, j] == 1)
Console.Write("*");
else if (floor[i, j] == 2)
Console.Write("T");
}
Console.WriteLine();
}
}
private static void Moves()
{
switch (direction)
{
case 0:
turtleX++;
break;
case 1:
turtleY++;
break;
case 2:
turtleX--;
break;
case 3:
turtleY--;
break;
default:
if (direction < 0)
direction = 3;
else
direction = 4;
Moves();
break;
}
if (penDown)
{
if (turtleX < 20 && turtleY < 20)
floor[turtleX, turtleY] = 1;
else
{
direction -= 2;
Moves();
}
}
}
}
}
Any quick help is appreciated. Thanks
There's one obvious situation where you end up looping endlessly. Imagine you're entering the Moves method and direction is 4:
private static void Moves()
{
switch (direction)
{
case 0:
//Nope
case 1:
//Nope
case 2:
//Nope
case 3:
//Nope
default:
if (direction < 0)
//Nope
else
direction = 4; //Okay, but it already was
Moves(); //And call myself again
The code cannot make any further progress and the call stack fills up with more and more calls to Moves() that are never going to finish.
I can't offer a correction because I don't understand what your code is meant to be doing. Break it down into smaller methods with clearer method names and XML documentation comments that describe what it does. Then makes sure that the code and comments agree.
I have no idea what the correct operation of a method called Moves is.
The default section of the switch statement in Moves should be this:
default:
if (direction < 0)
direction += 4;
else
direction -= 4;
Moves();
break;
since its purpose is to wrap the direction value such that it always remains in the range 0-3.

Why does the return rate of a game appear to vary when output by two different programs?

I have coded two C# programs, which use two different approaches to evaluate the outcome of a certain casino-style game (casino-style in the sense that the user pays points to take a turn, and sometimes receives points as a reward depending on that turn’s result). Program 1 calculates the average profitability of the best game play decision for each possible game state, starting at a round's end and working to the beginning. The average profitability of the starting game state is equivalent to, thus can be used to infer, the average profitability of the game as a whole. Program 1 also outputs a proper strategy for the game.
Program 2 accepts a strategy as input (I use the same strategy generated by Program 1), and simulates actual beginning-to-end game play using that strategy, cycling through many iterations of the game to gather statistics. This program outputs the return rate of the game based on the simulated trials (100% being breakeven).
Desired behavior: To produce correct and non-contradictory results in Program 1’s gamePlay.value variable for the starting game state (representing the game’s profitability in points), and Program 2’s returnRate variable (representing the game’s return rate).
Specific problem: Program 1’s gamePlay.value variable for the starting game state (Colorless, Colorless, Colorless) outputs 51.025 when the user inputs the same starting parameters as those which are hard-coded into Program 2 (namely, cost = 51 and baseBet = 50). A secondary task of Program 1 is to calculate the average number of turns remaining in the round, for each possible game state. Again, by noting this value for the starting state, the average number of turns in the round as a whole is known. There are, on average, 4.246 turns per round. By multiplying this number by the cost per turn, 51, we see that the average cost per round is 216.546. Adding the 51.025 profit yields 267.571, and dividing this number by the cost per round reveals a 123.563% return rate for the game.
This is not what Program 2 calculates, even using an extremely large number of game play samples. Some output samples, each of which are the result of one million game play turns, include:
1.00978242220553
1.00976014965254
1.00977590536083
1.0098289475708
1.00979315220468
123.563% and 100.98% are very far from each other.
Code to reproduce problem:
PROGRAM 1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace theBlindPainterAnalyzerSimplified
{
public partial class Form1 : Form
{
double cost;
double baseBet;
public Form1()
{
InitializeComponent();
}
private void calculateStrategyButton_Click(object sender, EventArgs e) // This is the primary code, analogous to main()
{
cost = Convert.ToDouble(textBox1.Text);
baseBet = Convert.ToDouble(textBox2.Text);
GameState[] gameStates = new GameState[10];
for (int h = 0; h < gameStates.Length; h++)
{
gameStates[h] = new GameState();
}
int i = 0;
foreach (var c in BuildCombinations(Enum.GetValues(typeof(OrderedColors)).Cast<OrderedColors>().Reverse().ToArray(), 3))
{
int j = 0;
foreach (var panel in c)
{
gameStates[i].colors[j] = panel;
j++;
}
i++;
}
foreach (var gameState in gameStates) // Stores the expected value of each decision from each game state
{
int numPreviousStrokes = 0;
for (int j = 0; j < gameState.colors.Length; j++)
{
if (gameState.colors[j] == OrderedColors.Purple)
{
numPreviousStrokes++;
}
else if (gameState.colors[j] == OrderedColors.Blue)
{
numPreviousStrokes += 2;
}
}
double zeroProfitability = 0;
double oneProfitability = checkProfitability(gameState, 1, gameStates);
double twoProfitability = -4;
double threeProfitability = -4;
if (numPreviousStrokes >= 2)
{
twoProfitability = checkProfitability(gameState, 2, gameStates);
}
if (numPreviousStrokes >= 3)
{
threeProfitability = checkProfitability(gameState, 3, gameStates);
}
if (zeroProfitability > oneProfitability && zeroProfitability > twoProfitability && zeroProfitability > threeProfitability)
{
gameState.optimalPlay = 0;
gameState.value = zeroProfitability;
}
else if (oneProfitability > zeroProfitability && oneProfitability > twoProfitability && oneProfitability > threeProfitability)
{
gameState.optimalPlay = 1;
gameState.value = oneProfitability;
}
else if (twoProfitability > zeroProfitability && twoProfitability > oneProfitability && twoProfitability > threeProfitability)
{
gameState.optimalPlay = 2;
gameState.value = twoProfitability;
}
else if (threeProfitability > zeroProfitability && threeProfitability > oneProfitability && threeProfitability > twoProfitability)
{
gameState.optimalPlay = 3;
gameState.value = threeProfitability;
}
else
{
MessageBox.Show("Draw!");
}
gameState.remainingTurnCount = checkRemainingTurnCount(gameState, gameStates);
richTextBox1.Text += gameState.colors[0] + "," + gameState.colors[1] + "," + gameState.colors[2] + "," + gameState.optimalPlay + "," + gameState.value + "," + gameState.remainingTurnCount + "\n";
}
}
private double checkProfitability(GameState state, int numStrokes, GameState[] gameStates) // Calculates the expected value of making a particular decision from a particular game state
{
double[] possiblePayoffs = new double[50000];
int pPIndex = 0;
double sumOfPossiblePayoffs = 0;
double averagePayoff = 0;
double payoff = -cost;
for (int i = 0; i < Math.Pow(3, numStrokes); i++)
{
int innerForIndex = i;
for (int j = 0; j < numStrokes; j++)
{
state.colors[innerForIndex % 3]++;
innerForIndex /= 3;
}
if ((int)state.colors[0] <= 2 && (int)state.colors[1] <= 2 && (int)state.colors[2] <= 2)
{
int numPurple = 0;
int numBlue = 0;
int numNonZeros = 0;
for (int panel = 0; panel <= 2; panel++)
{
if (state.colors[panel] == OrderedColors.Purple)
{
numPurple++;
}
if (state.colors[panel] == OrderedColors.Blue)
{
numBlue++;
}
}
if (numPurple != 0)
{
numNonZeros++;
}
if (numBlue != 0)
{
numNonZeros++;
}
switch (numPurple)
{
case 2:
payoff += (.7 * baseBet);
break;
case 3:
payoff += (2 * baseBet);
break;
}
switch (numBlue)
{
case 2:
payoff += baseBet;
break;
case 3:
payoff += (4.12 * baseBet);
break;
}
if (numPurple + numBlue == 3 && numPurple != 0 && numBlue != 0)
{
payoff += (4 * baseBet);
}
}
OrderedColors[] currentColors = (OrderedColors[])state.colors.Clone(); // Temporary clone of array used to find corrosponding game state
Array.Sort(currentColors);
Array.Reverse(currentColors);
foreach (var gameState in gameStates)
{
if (areArraysEqual(gameState.colors, currentColors))
{
payoff += gameState.value;
break;
}
}
possiblePayoffs[pPIndex] = payoff;
pPIndex++;
payoff = -cost;
innerForIndex = i;
for (int j = 0; j < numStrokes; j++)
{
state.colors[innerForIndex % 3]--;
innerForIndex /= 3;
}
}
for (int i = 0; i <= pPIndex; i++)
{
sumOfPossiblePayoffs += possiblePayoffs[i];
}
averagePayoff = sumOfPossiblePayoffs / pPIndex;
return averagePayoff;
}
private double checkRemainingTurnCount(GameState state, GameState[] gameStates)
{
double[] possibleTurnAverages = new double[50000];
int pTAIndex = 0;
double sumOfPossibleTurnAverages = 0;
double turns = -4;
if (state.optimalPlay == 0)
{
turns = 0;
}
else
{
for (int i = 0; i < Math.Pow(3, state.optimalPlay); i++)
{
int innerForIndex = i;
for (int j = 0; j < state.optimalPlay; j++)
{
state.colors[innerForIndex % 3]++;
innerForIndex /= 3;
}
if ((int)state.colors[0] <= 3 && (int)state.colors[1] <= 3 && (int)state.colors[2] <= 3)
{
OrderedColors[] currentColors = (OrderedColors[])state.colors.Clone(); // Temporary clone of array used to find corrosponding game state
Array.Sort(currentColors);
Array.Reverse(currentColors);
foreach (var gameState in gameStates)
{
if (areArraysEqual(gameState.colors, currentColors))
{
possibleTurnAverages[pTAIndex] = gameState.remainingTurnCount + 1;
pTAIndex++;
break;
}
}
}
else
{
possibleTurnAverages[i] = 1;
pTAIndex++;
}
innerForIndex = i;
for (int j = 0; j < state.optimalPlay; j++)
{
state.colors[innerForIndex % 3]--;
innerForIndex /= 3;
}
}
for (int i = 0; i <= pTAIndex; i++)
{
sumOfPossibleTurnAverages += possibleTurnAverages[i];
}
turns = sumOfPossibleTurnAverages / pTAIndex;
}
return turns;
}
private static IEnumerable<T[]> BuildCombinations<T>(T[] items, int itemsCountInCombination, int startIndex = 0) // Finds all possible unique game states; I did not write this code myself
{
if (itemsCountInCombination == 0)
{
yield return new T[0];
yield break;
}
for (int i = startIndex; i < items.Length; i++)
{
foreach (var combination in BuildCombinations(items, itemsCountInCombination - 1, i))
{
var c = new T[itemsCountInCombination];
c[0] = items[i];
Array.Copy(combination, 0, c, 1, combination.Length);
yield return c;
}
}
}
private bool areArraysEqual<T>(T[] array1, T[] array2)
{
if (Object.ReferenceEquals(array1, array2))
{
return true;
}
if (array1.Length != array2.Length)
{
return false;
}
for (int i = 0; i < array1.Length; i++)
{
if (array1[i].Equals(array2[i]) == false)
{
return false;
}
}
return true;
}
}
public class GameState
{
public OrderedColors[] colors = { OrderedColors.Colorless, OrderedColors.Colorless, OrderedColors.Colorless };
public int optimalPlay = -4; // The value 0 has a specific meaning
public double value = 0;
public double remainingTurnCount;
}
public enum OrderedColors
{
Colorless,
Purple,
Blue
}
}
__
PROGRAM 2
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace theBlindPainterTesterContinuousSimplified
{
public partial class Form1 : Form
{
Random rn1_3 = new Random();
float cost = 51;
float baseBet = 50;
static double startScore = 100000;
static double score = startScore;
int cycledPoints = 0;
double returnRate = 0;
bool isRoundOver = false;
OrderedColors[] panelColors = { OrderedColors.Colorless, OrderedColors.Colorless, OrderedColors.Colorless };
public Form1()
{
InitializeComponent();
}
private void startButton_Click(object sender, EventArgs e)
{
string strategyFileText;
using (StreamReader strategyFile = new StreamReader("strategy.txt"))
{
strategyFileText = strategyFile.ReadToEnd();
}
string[] strats = strategyFileText.Split('\n');
for (int h = 0; h < 1000000; h++)
{
isRoundOver = false;
int selectedPlay = selectPlay(strats);
if (selectedPlay == 0)
{
endRound();
}
else if (selectedPlay >= 1 && selectedPlay <= 3)
{
score = score - cost;
cycledPoints += Convert.ToInt32(cost);
for (int i = 0; i < selectedPlay; i++)
{
if (isRoundOver == false)
{
paintPanel();
}
}
payOut();
}
else
{
MessageBox.Show(selectedPlay + " is not a valid play.");
}
}
if (startScore != 0 && cycledPoints != 0)
{
returnRate = Math.Pow(score / startScore, startScore / cycledPoints);
}
else
{
MessageBox.Show("Division by zero error.");
}
richTextBox1.Text = returnRate.ToString();
}
// Retrieves the appropriate game play for the current panel colors
private int selectPlay(string[] strats)
{
int play = -4; // The value 0 has a specific meaning
Array.Sort(panelColors);
Array.Reverse(panelColors);
foreach (string strat in strats)
{
string[] stratComponents = strat.Split(',');
int matches = 0;
for (int j = 0; j <= 2; j++)
{
if (stratComponents[j] == panelColors[j].ToString())
{
matches++;
}
}
if (matches == 3)
{
play = Convert.ToInt32(stratComponents[3]);
break;
}
}
return play;
}
// Paints a single randomly selected panel
private void paintPanel()
{
int primedPanel = rn1_3.Next(1, 4);
if (panelColors[primedPanel - 1] == OrderedColors.Colorless)
{
panelColors[primedPanel - 1] = OrderedColors.Purple;
}
else if (panelColors[primedPanel - 1] == OrderedColors.Purple)
{
panelColors[primedPanel - 1] = OrderedColors.Blue;
}
else if (panelColors[primedPanel - 1] == OrderedColors.Blue)
{
endRound();
}
}
// Adjusts score and takes action if the game is over
private void payOut()
{
int numPurple = 0;
int numBlue = 0;
int numNonZeros = 0;
for (int panel = 0; panel <= 2; panel++)
{
if (panelColors[panel] == OrderedColors.Purple)
{
numPurple++;
}
if (panelColors[panel] == OrderedColors.Blue)
{
numBlue++;
}
}
if (numPurple != 0)
{
numNonZeros++;
}
if (numBlue != 0)
{
numNonZeros++;
}
switch (numPurple)
{
case 2:
score += (.7 * baseBet);
break;
case 3:
score += (2 * baseBet);
break;
}
switch (numBlue)
{
case 2:
score += baseBet;
break;
case 3:
score += (4.12 * baseBet);
break;
}
if (numPurple + numBlue == 3 && numPurple != 0 && numBlue != 0)
{
score += (4 * baseBet);
}
}
private void endRound()
{
isRoundOver = true;
for (int panel = 0; panel <= 2; panel++)
{
panelColors[panel] = OrderedColors.Colorless;
}
}
}
public enum OrderedColors
{
Colorless,
Purple,
Blue
}
}
__
What I Have Considered: The possible types of problems I have tried to categorize this as are programming logic errors, snowballing rounding errors, and casting errors. It is difficult to isolate the error(s) because Program 1 solves the game using backward induction, while Program 2 gathers information by playing the game start to finish many times, two fundamentally different approaches. I have spent a fairly substantial amount of time with Program 1 in the debugger, including working out the results for the last few game states on paper, and it seems to be functioning properly and to a very respectable precision, as far as I can tell. Program 2 is more difficult to do this with due to the inclusion of randomness in the game, but I have stepped through a small number of iterations and the calculations seem to me to be on point.
Can anyone clarify the reason that these two approaches to return rate calculation produce conflicting results?
The game (this is detailed info about the game being studied, feel free to skip this section): This game consists of three objects called panels, which the user paints. Each panel starts out Colorless. At first, the user must select 1, which paints one random panel. A Colorless panel will turn Purple when painted. A Purple panel will turn Blue when painted again. A Blue panel, when painted again, will immediately cause all panels to return to Colorless, and a new round begins. Once the user has painted a panel, he/she can, on the next turn, select 1 or 2, which will paint one random panel, or two random panels, respectively. Once two units of paint have been applied, the user can select 1, 2, or 3, and the appropriate result is applied. When a new round begins, only option 1 is available until 2 and 3 are unlocked again.
Each turn costs 51 points, regardless of whether 1, 2, or 3 is selected. There is a payout table, as laid out in the code, which may award points back to the user based on the resulting state of the panels. The user can also decide to start a new round at any time, and revert all panels to Colorless, which does not have a cost. The goal of the game is to earn rather than lose points, on average.
Below are my project folders, in case someone wishes to compile, as the interface is not contained in the above code.
http://www.fileconvoy.com/dfl.php?id=geb5da551f035649699958123114d58733569b2fb4

Tic-Tac-Toe programming

I'm trying to create a program for homework that displays a Tic-Tac-Toe board, and when the user clicks the button it displays a random number in all of the boxes. The number 1 = "X" and 0 = "O". I created 9 labels labeled "label1, label2...etc". Once the labels are full, I need to display who won, the letter X or O. I'm using arrays for this but am kinda of lost at this point. what do I need to do to display the random numbers into the labels. Here is the code I've written for the click event handler so far.
Random rand = new Random(2);
int click;
click = rand.Next(2);
const int ROWS = 3;
const int COLS = 3;
int[,] letters = new int[ROWS,COLS];
int ROW = ROWS;
int COL = COLS;
for (int row = 0; row < ROWS; ROW ++) {
for (int col = 0; col < COLS; COL ++) {
letters[row, col] = rand.Next(2);
int X = 1;//???
int O = 0;//???
label1.Text = [ROW,COL].ToString();//???
}
}
Here an attempt at an explanation:
first, you have the data to represent your problem:
const int ROWCOUNT = 3;
const int COLCOUNT = 3;
private int[,] letters = new int[ROWCOUNT,COLCOUNT];
Random rand = new Random(DateTime.Now.Ticks);
then you want to randomly fill that data:
private void randomize()
{
for( int row = 0; row < ROWCOUNT; row++ ){ //start with row=0, do row=row+1 until row no longer < ROWCOUNT
for( int col = 0; col < COLCOUNT; col++ ){
letters[row,col] = rand.nextInt(2);
}
}
}
finally, you want to display the array somewhere (in your case labels):
//These need to be added to a GridLayoutManager
private JLabel[,] labels = new JLabel[ROWCOUNT,COLCOUNT];
private void updateView(){
for( int row = 0; row < ROWCOUNT; row++ ){ //start with row=0, do row=row+1 until row no longer < ROWCOUNT
for( int col = 0; col < COLCOUNT; col++ ){
var current = letters[row,col];
var labelText = "O";
if( current > 0 )
labelText = "X";
labels[row,col].Text = labelText;
}
}
}
so, when the user clicks the button, you call:
randomize();
updateView();
hope it helps
from your comments, it seems setting the Label Text needs more explanation:
var labelText = "O";
if( current > 0 )
labelText = "X";
labels[row,col].Text = labelText;
maybe, i should have written it more like this:
String textForLabel = "O"; //0 represents O, 1 represents X
//test to see, if it really is a 0, not a 1
if( current != 0 ){
//oh, it is not a zero, therefore, set
textForLabel = "X";
}
JLabel labelAtRowAndCol = labels[row,col];
labelAtRowAndCol.Text = textForLabel;
I refuse to provide you the exact answer since you learning how to dot his is the entire point of this excerise.
Before I started the game I would randomly choose the first move: X or O.
I would then do the following:
1) I would place all the Labels into a collection.
2) I would randomly choose one of the Labels within the collection and change the Text property.
3) I would then remove the same Label from the collection
4) Rinse and Repeat.
You DO NOT need a two diminsional array for this.
In order to figure out the winner...I would keep track of the moves of each player. There is only a static number of winning moves in this game. Would be a simple task to determine if there were three X's in the top row or not.
#include<iostream>
#include<iomanip>
#include<set>
using namespace std;
char s[3][3] = {{'*','*','*'},{'*','*','*'},{'*','*','*'}};
void show(char os[3][3]);
int def[9];
void changeo(int n);
void changex(int n);
int stop();
set<int> cset;
int search (int n){
}
int main(){
int n; show(s);
int ss = 2;
cout<<endl;
while (stop()){
if (ss%2==0){
cout<<"player One(O) : enter n "; cin>>n;
if (!cset.count(n) && n<10){
cset.insert(n);
changeo(n);
show(s);
ss++;
}
else{
cout<<"invalid move"<<endl;
}
}
else{
cout<<"player Two(X) : enter n "; cin>>n;
if (!cset.count(n)&& n<10){
cset.insert(n);
changex(n);
show(s);
ss++;
}
}
}
cout<<"\nyou can see the winner"<<endl;
cout<<"your moves are "<<ss;
return 0;
}
void show(char s[3][3]){
cout<< setw(7)<< "1: " <<s[0][0]<<setw(5)<<"2: " <<s[0][1]<<setw(5)<<"3: " <<s[0][2]<<endl;
cout<< setw(7)<< "4: " <<s[1][0]<<setw(5)<<"5: " <<s[1][1]<<setw(5)<<"6: " <<s[1][2]<<endl;
cout<< setw(7)<< "7: " <<s[2][0]<<setw(5)<<"8: " <<s[2][1]<<setw(5)<<"9: " <<s[2][2]<<endl;
cout<<endl;
}
void changeo(int n){
switch(n){
case 1:
s[0][0] = 'O';
break;
case 2:
s[0][1] = 'O';
break;
case 3:
s[0][2] = 'O';
break;
case 4:
s[1][0] = 'O';
break;
case 5:
s[1][1] = 'O';
break;
case 6:
s[1][2] = 'O';
break;
case 7:
s[2][0] = 'O';
break;
case 8:
s[2][1] = 'O';
break;
case 9:
s[2][2] = 'O';
break;
}
}
void changex(int n){
switch(n){
case 1:
s[0][0] = 'X';
break;
case 2:
s[0][1] = 'X';
break;
case 3:
s[0][2] = 'X';
break;
case 4:
s[1][0] = 'X';
break;
case 5:
s[1][1] = 'X';
break;
case 6:
s[1][2] = 'X';
break;
case 7:
s[2][0] = 'X';
break;
case 8:
s[2][1] = 'X';
break;
case 9:
s[2][2] = 'X';
break;
}
}
int stop(){
int m=0;
for (int i=0; i<3; i++){
for (int j=0; j<3; j++){
if(s[i][j]=='*'){
m=1;
break;
}
}
}
return m;
}

Categories

Resources