Finding all of the outcomes for a Tic-Tac-Toe game - c#

I recently decided to type up some code in C sharp that determines the outcomes for a Tic-Tac-Toe game.
In my code, I received the results:
Total number of games:77088
214 tied
36533 x wins
40341 o wins
(following the rules of x goes first)
However, my results are vastly contradictory to the results on Google.
According to Wikipedia: Tic-tac-toe there are 138 different game outcomes with 91 won by x, 44 won by o and 3 tied
Most other websites say there are either 9!(352,880) or 3^9(19,683) ways to fill the board.
Through my personal experience and basic testing, I know there are many more than 3 ways to tie a game which invalidates the results presented by Wikipedia. Also, the pure math proposed by other websites witch use 9! and 3^9 fail to take into account games that are ended early.
So, am I mistaken, is everyone else mistaken?
My research:
A game cannot be won in less than 5 turns.
A game has finished once a victor has been found.
A victor is determined by a match of 3 vertically, horizontally or diagonally across any 3 cells.
My testing code : c sharp - ran in Unity
void Start()
{
int x=0;
int o=0;
int t=0;
int victor;
for (int i = 0; i < 9; i++)
{//turn 1 - no win
for (int b = 0; b < 9; b++)
{//turn 2 - no win
if (b == i) continue;
for (int c = 0; c < 9; c++)
{//turn 3 - no win
if (c == i || c == b) continue;
for (int d = 0; d < 9; d++)
{//tunr 4 - no win
if (d == i || d == b || d == c) continue;
for (int e = 0; e < 9; e++)
{//turn 5 - possible winner
if (e == i || e == b || e == c || e == d) continue;
TicTacToeGame ticTacToeGame = new TicTacToeGame();
ticTacToeGame.SetMove(i);
ticTacToeGame.SetMove(b);
ticTacToeGame.SetMove(c);
ticTacToeGame.SetMove(d);
victor = ticTacToeGame.SetMove(e);
if (victor > 0)
{
Debug.Log(ticTacToeGame.GetGame());
Debug.Log("The victor is " + (victor == 1 ? 'X' : (victor == 2 ? 'O' : ' ')));
switch (victor)
{
case 0:
t++;
break;
case 1:
x++;
break;
case 2:
o++;
break;
}
continue;
}
for (int f = 0; f < 9; f++)
{
if (f == i || f == b || f == c || f == d || f == e) continue;
TicTacToeGame ticTacToeGame6 = new TicTacToeGame();
ticTacToeGame.SetMove(i);
ticTacToeGame.SetMove(b);
ticTacToeGame.SetMove(c);
ticTacToeGame.SetMove(d);
ticTacToeGame.SetMove(e);
victor = ticTacToeGame.SetMove(f);
if (victor > 0)
{
Debug.Log(ticTacToeGame.GetGame());
Debug.Log("The victor is " + (victor == 1 ? 'X' : (victor == 2 ? 'O' : ' ')));
switch (victor)
{
case 0:
t++;
break;
case 1:
x++;
break;
case 2:
o++;
break;
}
continue;
}
for (int g = 0; g < 9; g++)
{
if (g == i || g == b || g == c || g == d || g == e || g==f) continue;
TicTacToeGame ticTacToeGame7 = new TicTacToeGame();
ticTacToeGame.SetMove(i);
ticTacToeGame.SetMove(b);
ticTacToeGame.SetMove(c);
ticTacToeGame.SetMove(d);
ticTacToeGame.SetMove(e);
ticTacToeGame.SetMove(f);
victor = ticTacToeGame.SetMove(g);
if (victor > 0)
{
Debug.Log(ticTacToeGame.GetGame());
Debug.Log("The victor is " + (victor == 1 ? 'X' : (victor == 2 ? 'O' : ' ')));
switch (victor)
{
case 0:
t++;
break;
case 1:
x++;
break;
case 2:
o++;
break;
}
continue;
}
for (int h = 0; h < 9; h++)
{
if (h == i || h == b || h == c || h == d || h == e || h == f || h==g) continue;
TicTacToeGame ticTacToeGame8 = new TicTacToeGame();
ticTacToeGame.SetMove(i);
ticTacToeGame.SetMove(b);
ticTacToeGame.SetMove(c);
ticTacToeGame.SetMove(d);
ticTacToeGame.SetMove(e);
ticTacToeGame.SetMove(f);
ticTacToeGame.SetMove(g);
victor = ticTacToeGame.SetMove(h);
if (victor > 0)
{
Debug.Log(ticTacToeGame.GetGame());
Debug.Log("The victor is " + (victor == 1 ? 'X' : (victor == 2 ? 'O' : ' ')));
switch (victor)
{
case 0:
t++;
break;
case 1:
x++;
break;
case 2:
o++;
break;
}
continue;
}
for (int j = 0; j < 9; j++)
{
if (j == i || j == b || j == c || j == d || j == e || j == f || j == g || j==h) continue;
TicTacToeGame ticTacToeGame9 = new TicTacToeGame();
ticTacToeGame.SetMove(i);
ticTacToeGame.SetMove(b);
ticTacToeGame.SetMove(c);
ticTacToeGame.SetMove(d);
ticTacToeGame.SetMove(e);
ticTacToeGame.SetMove(f);
ticTacToeGame.SetMove(g);
ticTacToeGame.SetMove(h);
victor = ticTacToeGame.SetMove(j);
Debug.Log(ticTacToeGame.GetGame());
Debug.Log("The victor is " + (victor == 1 ? "X" : (victor == 2 ? "O" : "Tied")));
switch (victor)
{
case 0:
t++;
break;
case 1:
x++;
break;
case 2:
o++;
break;
}
continue;
}
}
}
}
}
}
}
}
}
Debug.Log(t + " tied\n" + x + " x\n" + o + " o");
Debug.Log("Total : " + (t + x + o));
}
private class TicTacToeGame
{
int[] gameBoard = new int[9];
bool turn = true;
int victor = 0;
bool isActive = false;
public TicTacToeGame()
{
isActive = true;
}
public int SetMove(int i)
{
if (!isActive) return victor;
if (i < 0 || i > 8) throw new Exception("Invalid move : " + i);
gameBoard[i] = turn ? 1 : 2;
turn = !turn;
victor = CheckVictory();
if (victor!=0)
{
isActive = false;
}
return victor;
}
private int CheckVictory()
{
if(IsEqual(gameBoard[0], gameBoard[1], gameBoard[2]))
{
return gameBoard[0];
}
if (IsEqual(gameBoard[3], gameBoard[4], gameBoard[5]))
{
return gameBoard[3];
}
if (IsEqual(gameBoard[6], gameBoard[7], gameBoard[8]))
{
return gameBoard[6];
}
if (IsEqual(gameBoard[0], gameBoard[3], gameBoard[6]))
{
return gameBoard[6];
}
if (IsEqual(gameBoard[1], gameBoard[4], gameBoard[7]))
{
return gameBoard[1];
}
if (IsEqual(gameBoard[2], gameBoard[5], gameBoard[8]))
{
return gameBoard[2];
}
if (IsEqual(gameBoard[0], gameBoard[4], gameBoard[8]))
{
return gameBoard[0];
}
if (IsEqual(gameBoard[6], gameBoard[4], gameBoard[2]))
{
return gameBoard[6];
}
return 0;
}
private bool IsEqual(int a, int b, int c)
{
if (a == 0 || b == 0 || c == 0) return false;
return a == b && a == c;
}
public string GetGame()
{
return string.Format("{0}|{1}|{2}\n" +
"-----\n" +
"{3}|{4}|{5}\n" +
"-----\n" +
"{6}|{7}|{8}",
IntToChar(gameBoard[0]),
IntToChar(gameBoard[1]),
IntToChar(gameBoard[2]),
IntToChar(gameBoard[3]),
IntToChar(gameBoard[4]),
IntToChar(gameBoard[5]),
IntToChar(gameBoard[6]),
IntToChar(gameBoard[7]),
IntToChar(gameBoard[8]));
}
private char IntToChar(int i)
{
return i == 1 ? 'X' : (i == 2 ? 'O' : ' ');
}
}
Update ::
After reading some comments, I realized that there was a flaw in my code as it wasn't checking all outcomes but now that should be rectified. One issue that is not addressed would be rotations or reflections but if this data is to be used in practice then rotations and reflections should be included otherwise the computer will have to rotate and reflect every move before making a decision which may take as long or longer than running through an array of outcomes.
Either way, my data is still widely contradictory to results found online.

Related

How can I prevent players from overwriting one another in tic tac toe?

I have tried to program a tic tac toe game in C# (with the help of tutorials). Overall it seems to be working fine (although the amount of code seems very excessive so sorry for that) but there appears to be one problem: Say, player 1 decides on row 1, column 1 and player 2 does the same afterwards, then player 2 overwrites player 1.
So far, this is the code:
namespace TicTacToe
{
class Program
{
static int turns = 1;
static char[] board =
{
' ',' ',' ',' ',' ',' ',' ',' ',' '
};
static char playerSignature = 'X';
private static void Introduction()
{
Console.WriteLine("This is a simple TicTacToe game. Enter y if you have played before and n if you are new to this.");
string input1 = Console.ReadLine();
Console.Clear();
if (input1 == "n")
{
Console.WriteLine("TicTacToeRules:");
Console.WriteLine("1. The game is played on a grid that's 3 squares by 3 squares.");
Console.WriteLine("2. You are X, your friend is O. Players take turns putting their marks in empty squares.");
Console.WriteLine("3. The first player to get 3 of her marks in a row (up, down, across, or diagonally) is the winner.");
Console.WriteLine("4. When all 9 squares are full, the game is over.");
Console.WriteLine("If you have read the rules, press any key to continue.");
Console.ReadKey();
Console.Clear();
DrawBoard(board);
}
else
{
Console.WriteLine("Alright, let's get started, you are X, your friend is O.");
DrawBoard(board);
}
}
private static void PlayAgain()
{
Console.WriteLine("Play again? y/n");
string playagain = Console.ReadLine();
switch (playagain)
{
case "n":
Console.WriteLine("Thanks for playing!");
Console.Clear();
break;
case "y":
Console.Clear();
ResetBoard();
break;
}
}
private static void DrawBoard(char[] board)
{
string row = "| {0} | {1} | {2} |";
string sep = "|___|___|___|";
Console.WriteLine(" ___ ___ ___ ");
Console.WriteLine(row, board[0], board[1], board[2]);
Console.WriteLine(sep);
Console.WriteLine(row, board[3], board[4], board[5]);
Console.WriteLine(sep);
Console.WriteLine(row, board[6], board[7], board[8]);
Console.WriteLine(sep);
}
private static void ResetBoard()
{
char[] newBoard =
{
' ',' ',' ',' ',' ',' ',' ',' ',' '
};
board = newBoard;
DrawBoard(board);
turns = 0;
}
private static void Draw()
{
Console.WriteLine("It's a draw!\n" +
"Press any key to play again.");
Console.ReadKey();
ResetBoard();
//DrawBoard(board);
}
public static void Main()
{
Introduction();
while(true)
{
bool isrow = false;
bool iscol = false;
int row = 0;
int col = 0;
while (!isrow)
{
Console.WriteLine("Choose a row (1-3): ");
try
{
row = Convert.ToInt32(Console.ReadLine());
}
catch
{
Console.WriteLine("Please enter a number between 1 and 3.");
}
if (row == 1 || row == 2 || row == 3)
{
isrow = true;
}
else
{
Console.WriteLine("\nInvalid row!");
}
}
while (!iscol)
{
Console.WriteLine("Choose a column (1-3): ");
try
{
col = Convert.ToInt32(Console.ReadLine());
}
catch
{
Console.WriteLine("Please enter a number between 1 and 3.");
}
if (col == 1 || col == 2 || col == 3)
{
iscol = true;
}
else
{
Console.WriteLine("\nInvalid column!");
}
}
int[] input = { row, col };
int player = 2;
if (player == 2)
{
player = 1;
XorO(player, input);
}
else
{
player = 2;
XorO(player, input);
}
DrawBoard(board);
turns++;
CheckForDiagonal();
CheckForVertical();
CheckForHorizontal();
if (turns == 10 && (board[0] == playerSignature && board[1] == playerSignature && board[2] == playerSignature && board[3] == playerSignature &&
board[4] == playerSignature && board[5] == playerSignature && board[6] == playerSignature && board[7] == playerSignature && board[8] == playerSignature))
{
Draw();
}
}
}
private static void CheckForVertical()
{
char[] PlayerSignature = { 'O', 'X' };
foreach (char Signature in PlayerSignature)
{
if (board[0] == playerSignature && board[3] == playerSignature && board[6] == playerSignature ||
board[1] == playerSignature && board[4] == playerSignature && board[7] == playerSignature ||
board[2] == playerSignature && board[5] == playerSignature && board[8] == playerSignature)
{
if (playerSignature == 'X')
{
Console.WriteLine("Congratulations Player 1, that's a vertical win!\n" +
"Play again (y/n)?");
string playagain = Console.ReadLine();
if (playagain == "y")
{
Console.Clear();
ResetBoard();
turns = 0;
}
else
{
Console.Clear();
}
}
else
{
Console.WriteLine("Congratulations Player 2, that's a vertical win!\n" +
"Play again (y/n)?");
string playagain = Console.ReadLine();
if (playagain == "y")
{
Console.Clear();
ResetBoard();
turns = 0;
}
else
{
Console.Clear();
}
}
}
}
}
private static void CheckForHorizontal()
{
char[] PlayerSignature = { 'O', 'X' };
foreach (char Signature in PlayerSignature)
{
if (board[0] == playerSignature && board[1] == playerSignature && board[2] == playerSignature ||
board[3] == playerSignature && board[4] == playerSignature && board[5] == playerSignature ||
board[6] == playerSignature && board[7] == playerSignature && board[8] == playerSignature)
{
if (playerSignature == 'X')
{
Console.WriteLine("Congratulations Player 1, that's a horizontal win!\n" +
"Play again (y/n)?");
string playagain = Console.ReadLine();
if (playagain == "y")
{
Console.Clear();
ResetBoard();
turns = 0;
}
else
{
Console.Clear();
}
}
else
{
Console.WriteLine("Congratulations Player 2, that's a horizontal win!\n" +
"Play again (y/n)?");
string playagain = Console.ReadLine();
if (playagain == "y")
{
Console.Clear();
ResetBoard();
turns = 0;
}
else
{
Console.Clear();
}
}
}
}
}
private static void CheckForDiagonal()
{
char[] PlayerSignature = { 'O', 'X' };
foreach (char Signature in PlayerSignature)
{
if (board[6] == playerSignature && board[4] == playerSignature && board[2] == playerSignature ||
board[0] == playerSignature && board[4] == playerSignature && board[8] == playerSignature)
{
if (playerSignature == 'X')
{
Console.WriteLine("Congratulations Player 1, that's a diagonal win!\n" +
"Play again (y/n)?");
string playagain = Console.ReadLine();
if (playagain == "y")
{
Console.Clear();
ResetBoard();
turns = 0;
}
else
{
Console.Clear();
}
}
else
{
Console.WriteLine("Congratulations Player 2, that's a diagonal win!\n" +
"Play again (y/n)?");
string playagain = Console.ReadLine();
if (playagain == "y")
{
Console.Clear();
ResetBoard();
turns = 0;
}
else
{
Console.Clear();
}
}
}
}
}
private static void XorO(int player, int[] input)
{
if (player == 1)
{
playerSignature = 'X';
}
else if (player == 2)
{
playerSignature = 'O';
}
if (input[0] == 1 && input[1] == 1)
{
board[0] = playerSignature;
}
else if (input[0] == 1 && input[1] == 2)
{
board[1] = playerSignature;
}
else if (input[0] == 1 && input[1] == 3)
{
board[2] = playerSignature;
}
else if (input[0] == 2 && input[1] == 1)
{
board[3] = playerSignature;
}
else if (input[0] == 2 && input[1] == 2)
{
board[4] = playerSignature;
}
else if (input[0] == 2 && input[1] == 3)
{
board[5] = playerSignature;
}
else if (input[0] == 3 && input[1] == 1)
{
board[6] = playerSignature;
}
else if (input[0] == 3 && input[1] == 2)
{
board[7] = playerSignature;
}
else if (input[0] == 3 && input[1] == 3)
{
board[8] = playerSignature;
}
}
}
}
I have tried adding something like this: if(input[0] == 1 && input[1] == 1 && (board[0] != 'X' && board[0] != 'O') in the XorO method. But that didn't solve my issue.
Does somebody maybe have some suggestions as to how I can fix that?
You are doing way too much work in some of those methods...
For instance, here's a shorter XorO() method that also makes sure the spot is BLANK before assigning it to a player:
private static void XorO(int player, int[] input)
{
playerSignature = (player == 1) ? 'X' : 'O';
int index = ((input[0] - 1) * 3) + (input[1] - 1);
if (board[index] == ' ') {
board[index] = playerSignature;
}
else {
// ... output an error message? ...
Console.WriteLine("That spot is already taken!");
}
}
Could you maybe explain why you set index the way you did?
Sure! Here is the layout of the board, 3 rows with 3 cols, and the corresponding Index value of each position:
1 2 3
1 0 1 2
2 3 4 5
3 6 7 8
Note that because there are 3 columns, the value of the Index as we move down from one row to the next in the same column goes up by 3. Also note that the starting values in column 1 for each row are 0, 3, and 6, which are all multiples of 3. So to convert your row value from 1, 2, and 3 into 0, 3, and 6, we first subtract 1 from the row value and then multiply it by 3.
Next, each column simply increments by one as you move to the right. Thus we subtract one from the column value and add that to the computed beginning row value. This maps the (row, col) to the indices 0 through 8, seen here as a single dimension array:
1,1 | 1,2 | 1,3 | 2,1 | 2,2 | 2,3 | 3,1 | 3,2 | 3,3
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
But how was am I supposed to think of something like that? I would
never have thought of that.
It's a fairly common setup to represent a 2D structure in a single dimensional array, known as a compact layout. The math involved to convert a row/column to the equivalent index value or vice-versa is just something that all programmers learn at some point.
Lot of refactoring here, look closely:
class Program
{
static int turns;
static char[] board;
static bool playerOne;
public static void Main(string[] args)
{
Introduction();
bool playAgain = true;
while (playAgain)
{
ResetBoard();
bool gameOver = false;
while (!gameOver)
{
DrawBoard(board);
int row = getNumber(true);
int col = getNumber(false);
if (XorO(row, col)) {
turns++; // valid move was made
String msg = "";
String playerNumber = playerOne ? "1" : "2";
if (CheckForDiagonal())
{
gameOver = true;
msg = "Congratulations Player " + playerNumber + ", that's a diagonal win!";
}
else if (CheckForVertical())
{
gameOver = true;
msg = "Congratulations Player " + playerNumber + ", that's a vertical win!";
}
else if (CheckForHorizontal())
{
gameOver = true;
msg = "Congratulations Player " + playerNumber + ", that's a horizontal win!";
}
else if (turns == 9)
{
gameOver = true;
msg = "It's a draw!";
}
else
{
playerOne = !playerOne;
}
if (gameOver)
{
DrawBoard(board); // show last move
Console.WriteLine(msg);
}
}
}
Console.WriteLine("Play again (y/n)?");
string response = Console.ReadLine().ToLower();
playAgain = (response == "y");
}
}
private static void ResetBoard()
{
turns = 0;
playerOne = true;
board = new char[] {
' ',' ',' ',' ',' ',' ',' ',' ',' '
};
}
private static void Introduction()
{
Console.WriteLine("This is a simple TicTacToe game.\nEnter y if you have played before and n if you are new to this.");
string input1 = Console.ReadLine().ToLower();
Console.Clear();
if (input1 == "n")
{
Console.WriteLine("TicTacToeRules:");
Console.WriteLine("1. The game is played on a grid that's 3 squares by 3 squares.");
Console.WriteLine("2. You are X, your friend is O. Players take turns putting their marks in empty squares.");
Console.WriteLine("3. The first player to get 3 of her marks in a row (up, down, across, or diagonally) is the winner.");
Console.WriteLine("4. When all 9 squares are full, the game is over.");
Console.WriteLine("If you have read the rules, press any key to continue.");
Console.ReadKey();
Console.Clear();
}
else
{
Console.WriteLine("Alright, let's get started, you are X, your friend is O.");
}
}
private static void DrawBoard(char[] board)
{
Console.WriteLine(" ___ ___ ___ ");
for(int r=1; r<=3;r++)
{
Console.Write("|");
for(int c=1; c<=3; c++)
{
Console.Write(" {0} |", board[(r - 1) * 3 + (c - 1)]);
}
Console.WriteLine();
Console.WriteLine("|___|___|___|");
}
}
private static int getNumber(bool row)
{
int value = -1;
string description = row ? "row" : "column";
bool isValid = false;
while (!isValid)
{
Console.Write("Player '" + (playerOne ? "X" : "O") + "', choose a " + description + " (1-3): ");
if (int.TryParse(Console.ReadLine(), out value))
{
if (value >= 1 && value <= 3)
{
isValid = true;
}
else
{
Console.WriteLine("Please enter a number between 1 and 3.");
}
}
else
{
Console.WriteLine("\nInvalid " + description + "!");
}
}
return value;
}
private static bool XorO(int row, int col)
{
int index = ((row - 1) * 3) + (col - 1);
if (board[index] == ' ')
{
board[index] = playerOne ? 'X' : 'O';
return true;
}
else
{
Console.WriteLine("That spot is already taken!");
return false;
}
}
private static bool CheckForDiagonal()
{
return ((board[6] != ' ' && board[4] == board[6] && board[2] == board[6]) ||
(board[0] != ' ' && board[4] == board[0] && board[8] == board[0]));
}
private static bool CheckForVertical()
{
for(int c=0; c<=2; c++)
{
if (board[c] != ' ' && board[c+3] == board[c] && board[c+6] == board[c])
{
return true;
}
}
return false;
}
private static bool CheckForHorizontal()
{
for (int r=0; r<=6; r=r+3)
{
if (board[r] != ' ' && board[r + 1] == board[r] && board[r + 2] == board[r])
{
return true;
}
}
return false;
}
}

Is it possible to escape Json string using System.Text.Json [duplicate]

Are there any classes/functions available to be used for easy JSON escaping? I'd rather not have to write my own.
I use System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
For those using the very popular Json.Net project from Newtonsoft the task is trivial:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(#"a\b");
Console.WriteLine(s);
....
This code prints:
"a\\b"
That is, the resulting string value contains the quotes as well as the escaped backslash.
Building on the answer by Dejan, what you can do is import System.Web.Helpers .NET Framework assembly, then use the following function:
static string EscapeForJson(string s) {
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
}
The Substring call is required, since Encode automatically surrounds strings with double quotes.
Yep, just add the following function to your Utils class or something:
public static string cleanForJSON(string s)
{
if (s == null || s.Length == 0) {
return "";
}
char c = '\0';
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
String t;
for (i = 0; i < len; i += 1) {
c = s[i];
switch (c) {
case '\\':
case '"':
sb.Append('\\');
sb.Append(c);
break;
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ') {
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
} else {
sb.Append(c);
}
break;
}
}
return sb.ToString();
}
I have used following code to escape the string value for json.
You need to add your '"' to the output of the following code:
public static string EscapeStringValue(string value)
{
const char BACK_SLASH = '\\';
const char SLASH = '/';
const char DBL_QUOTE = '"';
var output = new StringBuilder(value.Length);
foreach (char c in value)
{
switch (c)
{
case SLASH:
output.AppendFormat("{0}{1}", BACK_SLASH, SLASH);
break;
case BACK_SLASH:
output.AppendFormat("{0}{0}", BACK_SLASH);
break;
case DBL_QUOTE:
output.AppendFormat("{0}{1}",BACK_SLASH,DBL_QUOTE);
break;
default:
output.Append(c);
break;
}
}
return output.ToString();
}
In .Net Core 3+ and .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
The methods offered here are faulty.
Why venture that far when you could just use System.Web.HttpUtility.JavaScriptEncode ?
If you're on a lower framework, you can just copy paste it from mono
Courtesy of the mono-project #
https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
{
if (string.IsNullOrEmpty(value))
return addDoubleQuotes ? "\"\"" : string.Empty;
int len = value.Length;
bool needEncode = false;
char c;
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
{
needEncode = true;
break;
}
}
if (!needEncode)
return addDoubleQuotes ? "\"" + value + "\"" : value;
var sb = new System.Text.StringBuilder();
if (addDoubleQuotes)
sb.Append('"');
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
sb.AppendFormat("\\u{0:x4}", (int)c);
else switch ((int)c)
{
case 8:
sb.Append("\\b");
break;
case 9:
sb.Append("\\t");
break;
case 10:
sb.Append("\\n");
break;
case 12:
sb.Append("\\f");
break;
case 13:
sb.Append("\\r");
break;
case 34:
sb.Append("\\\"");
break;
case 92:
sb.Append("\\\\");
break;
default:
sb.Append(c);
break;
}
}
if (addDoubleQuotes)
sb.Append('"');
return sb.ToString();
}
This can be compacted into
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{
private static bool NeedEscape(string src, int i)
{
char c = src[i];
return c < 32 || c == '"' || c == '\\'
// Broken lead surrogate
|| (c >= '\uD800' && c <= '\uDBFF' &&
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
// Broken tail surrogate
|| (c >= '\uDC00' && c <= '\uDFFF' &&
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
// To produce valid JavaScript
|| c == '\u2028' || c == '\u2029'
// Escape "</" for <script> tags
|| (c == '/' && i > 0 && src[i - 1] == '<');
}
public static string EscapeString(string src)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int start = 0;
for (int i = 0; i < src.Length; i++)
if (NeedEscape(src, i))
{
sb.Append(src, start, i - start);
switch (src[i])
{
case '\b': sb.Append("\\b"); break;
case '\f': sb.Append("\\f"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case '\t': sb.Append("\\t"); break;
case '\"': sb.Append("\\\""); break;
case '\\': sb.Append("\\\\"); break;
case '/': sb.Append("\\/"); break;
default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));
break;
}
start = i + 1;
}
sb.Append(src, start, src.Length - start);
return sb.ToString();
}
}
I ran speed tests on some of these answers for a long string and a short string. Clive Paterson's code won by a good bit, presumably because the others are taking into account serialization options. Here are my results:
Apple Banana
System.Web.HttpUtility.JavaScriptStringEncode: 140ms
System.Web.Helpers.Json.Encode: 326ms
Newtonsoft.Json.JsonConvert.ToString: 230ms
Clive Paterson: 108ms
\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\"things\to\escape\some\long\path\with\lots"\of\things\to\escape
System.Web.HttpUtility.JavaScriptStringEncode: 2849ms
System.Web.Helpers.Json.Encode: 3300ms
Newtonsoft.Json.JsonConvert.ToString: 2827ms
Clive Paterson: 1173ms
And here is the test code:
public static void Main(string[] args)
{
var testStr1 = "Apple Banana";
var testStr2 = #"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";
foreach (var testStr in new[] { testStr1, testStr2 })
{
var results = new Dictionary<string,List<long>>();
for (var n = 0; n < 10; n++)
{
var count = 1000 * 1000;
var sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.HttpUtility.JavaScriptStringEncode(testStr);
}
var t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.Helpers.Json.Encode(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = Newtonsoft.Json.JsonConvert.ToString(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = cleanForJSON(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Clive Paterson").Add(t);
}
Console.WriteLine(testStr);
foreach (var result in results)
{
Console.WriteLine(result.Key + ": " + Math.Round(result.Value.Skip(1).Average()) + "ms");
}
Console.WriteLine();
}
Console.ReadLine();
}
I would also recommend using the JSON.NET library mentioned, but if you have to escape unicode characters (e.g. \uXXXX format) in the resulting JSON string, you may have to do it yourself. Take a look at Converting Unicode strings to escaped ascii string for an example.
I nice one-liner, used JsonConvert as others have but added substring to remove the added quotes and backslash.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
What about System.Web.Helpers.Json.Encode(...) (see http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111).aspx)?
String.Format("X", c);
That just outputs: X
Try this instead:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
There's a Json library at Codeplex
I chose to use System.Web.Script.Serialization.JavaScriptSerializer.
I have a small static helper class defined as follows:
internal static partial class Serialization
{
static JavaScriptSerializer serializer;
static Serialization()
{
serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
}
public static string ToJSON<T>(T obj)
{
return serializer.Serialize(obj);
}
public static T FromJSON<T>(string data)
{
if (Common.IsEmpty(data))
return default(T);
else
return serializer.Deserialize<T>(data);
}
}
To serialize anything I just call Serialization.ToJSON(itemToSerialize)
To deserialize I just call Serialization.FromJSON<T>(jsonValueOfTypeT)

Check if won in Tic Tac Toe 2D array c#

Console App C#
I made a 2D array to represent a grid for the game. I cant find a way to check if the player has won.
I tried many things and searched online and I cant find it
I tried to loop thru the grid and check each one of the elements inside that row/column
I would love to get the explanation of why its not working and how to do it instead of the code answer.
public static void Win_check()
{
for (int i = 0; i < 3; i++)
{
if (grid[1, i] == 'x' && grid[1, i] == 'x' && grid[1, i] == 'x')
{
gameStatus = 'x';
}
if (grid[2, i] == 'o' && grid[2, i] == 'o' && grid[2, i] == 'o')
{
gameStatus = 'o';
}
if (grid[3, i] == 'o' && grid[3, i] == 'o' && grid[3, i] == 'o')
{
gameStatus = 'o';
}
if (grid[i, 1] == 'x' && grid[i, 1] == 'x' && grid[i, 1] == 'x')
{
gameStatus = 'x';
}
if (grid[i, 2] == 'o' && grid[i, 2] == 'o' && grid[i, 2] == 'o')
{
gameStatus = 'o';
}
if (grid[i, 3] == 'o' && grid[i, 3] == 'o' && grid[i, 3] == 'o')
{
gameStatus = 'o';
}
}
}
I suggest enumerating all the lines which bring win: 3 horizontal, 3 vertical and finally 2 diagonals.
private static IEnumerable<char[]> Lines(char[,] field) {
char[] result;
int size = Math.Min(field.GetLength(0), field.GetLength(1));
for (int r = 0; r < size; ++r) {
result = new char[size];
for (int c = 0; c < size; ++c)
result[c] = field[r, c];
yield return result;
}
for (int c = 0; c < size; ++c) {
result = new char[size];
for (int r = 0; r < size; ++r)
result[r] = field[r, c];
yield return result;
}
result = new char[size];
for (int d = 0; d < size; ++d)
result[d] = field[d, d];
yield return result;
result = new char[size];
for (int d = 0; d < size; ++d)
result[d] = field[d, size - d - 1];
yield return result;
}
Then you can easily query these lines with a help of Linq:
using System.Linq;
...
private static bool IsWon(char[,] field, char who) {
return Lines(field).Any(line => line.All(item => item == who));
}
For instance:
char[,] field = new char[,] {
{ 'x', 'o', 'o'},
{ 'x', 'o', ' '},
{ 'o', 'x', 'x'},
};
// Is field won by x?
Console.WriteLine(IsWon(field, 'x') ? "Y" : "N");
// Is field won by o?
Console.WriteLine(IsWon(field, 'o') ? "Y" : "N");

find common substrings in 2 string in c#

I have strings like:
1) Cookie:ystat_tw_ss376223=9_16940400_234398;
2) Cookie:zynga_toolbar_fb_uid=1018132522
3) GET /2009/visuels/Metaboli_120x600_UK.gif HTTP/1.1
4) GET /2010/07/15/ipad-3hk-smv-price-hk/ HTTP/1.1
1 ad 2 have common substtring{cookie:}
3 and 4 have common substtring{GET /20, HTTP/1.1}
I want to find all common substrings that have the length more than three characters(contain space character) between 2 strings.(like 1 and 2)
i want to code in c#. i have a program but it has some problems.
Could anyone help me?
public static string[] MyMCS2(string a, string b)
{
string[] st = new string[100];
// List<string> st = new List<string>();
List<char> f = new List<char>();
int ctr = 0;
char[] str1 = a.ToCharArray();
char[] str2 = b.ToCharArray();
int m = 0;
int n = 0;
while (m < str1.Length)
{
for (n = 0; n < str2.Length; n++)
{
if (m < str1.Length)
{
if (str1[m] == str2[n])
{
if ((m > 1) && (n > 1) &&(str1[m - 1] == str2[n - 1]) && (str1[m - 2] == str2[n - 2]))
{
//f[m]= str1[m];
f.Add(str1[m]);
char[] ff = f.ToArray();
string aaa = new string(ff);
if (aaa.Length >= 3)
{
st[ctr] = aaa + "()";
//st.Add(aaa);
ctr++;
}
kk = m;
m++;
}
else if ((n == 0) ||(n == 1))
{
f.Add(str1[m]);
kk = m;
m++;
}
else
f.Clear();
}
//else if ((str1[m] == str2[n]) && (m == str1.Length - 1) && (n == str2.Length - 1))
//{
// f.Add(str1[m]);
// char[] ff = f.ToArray();
// string aaa = new string(ff);
// if (aaa.Length >= 3)
// {
// st[ctr] = aaa;
// ctr++;
// }
// // m++;
//}
else if ((str1[m] != str2[n]) && (n == (str2.Length - 1)))
{
m++;
}
else if ((m > 1) && (n > 1) && (str1[m] != str2[n]) && (str1[m - 1] == str2[n - 1]) && (str1[m - 2] == str2[n - 2]) && (str1[m - 3] == str2[n - 3]))
{
//
char[] ff = f.ToArray();
string aaa = new string(ff);
if (aaa.Length >= 3)
{
st[ctr] = aaa + "()" ;
//st.Add(aaa);
ctr++;
f.Clear();
}
//f.Clear();
//for (int h = 0; h < ff.Length; h++)
//{
// f[h] = '\0';
//}
}
else if (str1[m] != str2[n])
continue;
}
}
}
//int gb = st.Length;
return st;
}
This is an exact matching problem not a substring. You can solve it with aho-corasick algorithm. Use the first string and compute a finite state machine. Then process the search string. You can extend the aho-corasick algorithm to use a wildcard and search also for substrings. You can try this animated example: http://blog.ivank.net/aho-corasick-algorithm-in-as3.html

Best way to put user input into generated javascript?

I need for someone to be able to put some text into a page and then this gets sent to the server, saved in the database, and else where this text is put into a javascript variable.
Basically like this:
Write("var myVar=\""+MyData+"\";");
What is the best way of escaping this data? Is there anything out there already to deal with things like ' and " and new lines? Is base64 my only option?
My serverside framework/language is ASP.Net/C#
You should use WPL:
Write("var myVar=" + Encoder.JavaScriptEncode(MyData, true) + ";");
if you don't want to reference the library, you can use the following function (adapted from the .Net source):
public static void QuoteString(this string value, StringBuilder b) {
if (String.IsNullOrEmpty(value))
return "";
var b = new StringBuilder();
int startIndex = 0;
int count = 0;
for (int i = 0; i < value.Length; i++) {
char c = value[i];
// Append the unhandled characters (that do not require special treament)
// to the string builder when special characters are detected.
if (c == '\r' || c == '\t' || c == '\"' || c == '\'' || c == '<' || c == '>' ||
c == '\\' || c == '\n' || c == '\b' || c == '\f' || c < ' ') {
if (b == null) {
b = new StringBuilder(value.Length + 5);
}
if (count > 0) {
b.Append(value, startIndex, count);
}
startIndex = i + 1;
count = 0;
}
switch (c) {
case '\r':
b.Append("\\r");
break;
case '\t':
b.Append("\\t");
break;
case '\"':
b.Append("\\\"");
break;
case '\\':
b.Append("\\\\");
break;
case '\n':
b.Append("\\n");
break;
case '\b':
b.Append("\\b");
break;
case '\f':
b.Append("\\f");
break;
case '\'':
case '>':
case '<':
AppendCharAsUnicode(b, c);
break;
default:
if (c < ' ') {
AppendCharAsUnicode(b, c);
} else {
count++;
}
break;
}
}
if (b == null) {
b.Append(value);
}
if (count > 0) {
b.Append(value, startIndex, count);
}
return b.ToString();
}

Categories

Resources