Checking letter position and if its the correct letter - c#

Im creating a game that generates a random word and then lets the user guess the word.
After the user enters his word the game will compare them and return what letter were correct and if they had the right position. Right now it return differents results when i input the same word.
This is what i have so far:
class Game
{
public string CorrectPlace;
public string WrongPlace;
public string NoneExist;
public string CorrectWord;
public string InputWord; // the word the uis
public int points;
public string[] Wordarray = new string[] { "radar", "andar", "raggar", "rapar", "raser", "rastar", "rikas" };
public string getRandomWord(string names)
{
Random ran = new Random();
return Wordarray[(ran.Next(0,Wordarray.Length-1))];
}
public void CheckWords(string name)
{
InputWord.ToCharArray();
CorrectWord = getRandomWord(CorrectWord); // store the random word in a string
for (int i = 0; i < CorrectWord.Length; i++)
{
if (InputWord[i] == CorrectWord[i])
MessageBox.Show("Letter #" + (i + 1).ToString() + " was correct!");
else
break;
}
}
}
Im calling the method in my form
private void button1_Click(object sender, EventArgs e)
{
Game nc = new Game();
nc.InputWord = textBox1.Text;
nc.CheckWords(nc.InputWord);
}

Try like this:
class Game
{
public string CorrectPlace;
public string WrongPlace;
public string NoneExist;
public string CorrectWord;
public string InputWord;
public int points;
public string[] Wordarray = null;
public string getRandomWord(string names)
{
Random ran = new Random();
return Wordarray[(ran.Next(0,Wordarray.Length-1))];
}
public void Game()
{
Wordarray = new string[] { "radar", "andar", "raggar", "rapar", "raser", "rastar", "rikas" }
CorrectWord = getRandomWord(); // store the random word in a string
}
public void CheckWords(string name)
{
for (int i = 0; i < CorrectWord.Length; i++)
{
if (InputWord[i] == CorrectWord[i])
MessageBox.Show("Letter #" + (i + 1).ToString() + " was correct!");
else
break;
}
}
}
The idea behind the scene is to get a random word when game starts( an instance of class Game instantiated) and then compare it with the user input in CheckWords method.
I would suggest to do not call MessageBox.show in a loop, it will popup every time a match exists.
occur

Change the Code Like this. Please let me know if you have any issues.
class Game
{
public string CorrectWord = null;
public string InputWord; // the word the uis
public int points;
public string[] Wordarray = new string[] { "radar", "andar", "raggar", "rapar", "raser", "rastar", "rikas" };
public string getRandomWord()
{
Random ran = new Random();
return Wordarray[(ran.Next(0, Wordarray.Length - 1))];
}
public void Newgame()
{
}
public void CheckWords(string name)
{
char[] charInputWord = name.ToCharArray();
CorrectWord = getRandomWord(); // store the random word in a string
Console.WriteLine("Random Word " + CorrectWord);
Console.WriteLine("User Word " + name);
char[] charCorrectWord = CorrectWord.ToCharArray();
for (int i = 0; i < charInputWord.Length; i++)
{
if (charInputWord[i] == charCorrectWord[i])
Console.WriteLine("Letter #" + (i + 1).ToString() + " was correct!");
else
break;
}
}
}
class Program
{
static void Main(string[] args)
{
Game ab = new Game();
ab.CheckWords("raser");
Console.ReadLine();
}
}

Both names and name are never used, and seem unneeded.
It looks like you want something like this (converted to console printing since I don't have your UI source)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WordGame
{
class Game
{
static void Main(string[] args)
{
Game g = new Game();
bool gameOver = false;
while (!gameOver)
{
Console.WriteLine("Enter a guess (or type 'exit' to exit):");
string answer = Console.ReadLine();
if (answer.ToLower() == "exit")
break;
if (g.CheckWord(answer))
{
Console.WriteLine("You win!");
while (true)
{
Console.WriteLine("Play Again (y/n)?");
answer = Console.ReadLine().ToLower();
if (answer == "n")
{
gameOver = true;
break;
}
else if (answer == "y")
{
g.ChooseRandomWord();
break;
}
}
}
}
}
public string CorrectWord;
public string[] Wordarray = new string[] { "radar", "andar", "raggar", "rapar", "raser", "rastar", "rikas" };
private Random ran = new Random();
public Game()
{
ChooseRandomWord();
}
public void ChooseRandomWord()
{
CorrectWord = Wordarray[(ran.Next(0, Wordarray.Length - 1))];
}
public bool CheckWord(string guess)
{
if (guess.Trim() == CorrectWord)
{
return true;
}
string guessLower = guess.Trim().ToLower();
string correctLower = CorrectWord.ToLower();
for (int i = 0; i < correctLower.Length; i++)
{
if (guessLower[i] == correctLower[i])
Console.Write(guess[i]);
else
Console.Write("#");
}
Console.WriteLine();
return false;
}
}
}

Related

If/else statement is returning false, even though the condition should be true. (C#)

I'm currently trying to build a tic-tac-toe game in C# as of right now. Now, I've gotten most of the whole game set up. Below is the complete code for my project as of rn:
// Main code.
Game newGame = new();
newGame.RunGame();
// Classes
internal class Game
{
private Player[] Players;
private Updater GameUpdater;
private Board GameBoard;
public Game()
{
Players = new Player[2] { new(PlayerSymbol.X), new(PlayerSymbol.O) };
GameUpdater = new();
GameBoard = new();
}
public void RunGame()
{
while (true)
{
GameBoard.DisplayBoard();
int currentPlayer = GameUpdater.SendPlayerTurnInfo();
int playerInput = Players[currentPlayer].GetUserInput(); // The position the player wants to place their X/O
bool playerInputtedValidNumber = GameUpdater.VerifyUserHasInputValidNumber(playerInput);
if (playerInputtedValidNumber)
{
bool playerInputtedUnusedNumber = GameUpdater.VerifyUserHasInputUnusedSpot(GameBoard.SendBoardPiecesData(--playerInput));
if (playerInputtedUnusedNumber)
{
PlayerSymbol currentPlayerSymbol = Players[currentPlayer].SendPlayerSymbol(); // The symbol of the current player.
GameBoard.UpdateBoardPiecesData(playerInput, currentPlayerSymbol);
}
else
{
Console.WriteLine("This position has already been used!");
continue;
}
}
else
{
Console.WriteLine("Inputted an invalid position!");
continue;
}
}
}
}
internal class Board
{
private string[]? BoardPieces;
private string? BoardDisplay;
public Board()
{
BoardPieces = new string[9] { " ", " ", " ", " ", " ", " ", " ", " ", " " };
BoardDisplay = $" {BoardPieces[0]} | {BoardPieces[1]} | {BoardPieces[2]} \n---+---+---\n {BoardPieces[3]} | {BoardPieces[4]} | {BoardPieces[5]} \n---+---+---\n {BoardPieces[6]} | {BoardPieces[7]} | {BoardPieces[8]} ";
}
public void DisplayBoard()
{
Console.WriteLine(BoardDisplay);
}
public string SendBoardPiecesData(int userInput)
{
return BoardPieces[userInput]; // No issue with null since the number will be automatically checked for null beforehand.
}
public void UpdateBoardPiecesData(int userInput, PlayerSymbol playerSymbol)
{
BoardPieces[userInput] = $"{playerSymbol}";
BoardDisplay = $" {BoardPieces[0]} | {BoardPieces[1]} | {BoardPieces[2]} \n---+---+---\n {BoardPieces[3]} | {BoardPieces[4]} | {BoardPieces[5]} \n---+---+---\n {BoardPieces[6]} | {BoardPieces[7]} | {BoardPieces[8]} ";
}
}
internal class Updater
{
private int PlayerIndicator;
public Updater()
{
PlayerIndicator = 1;
}
public int SendPlayerTurnInfo()
{
if (PlayerIndicator == 1)
{
PlayerIndicator = 0;
return PlayerIndicator;
} else
{
PlayerIndicator = 1;
return PlayerIndicator;
}
}
public bool VerifyUserHasInputValidNumber(int userInput)
{
Console.WriteLine(userInput);
if (userInput >= 0 || userInput <= 10)
{
return false;
} else
{
return true;
}
}
public bool VerifyUserHasInputUnusedSpot(string userInput)
{
if (userInput == "X" || userInput == "O") return false;
else return true;
}
}
internal class Player
{
private PlayerSymbol PlayerSymbol;
public Player(PlayerSymbol playerSymbol)
{
PlayerSymbol = playerSymbol;
}
public int GetUserInput()
{
Console.Write($"It is currently {PlayerSymbol}'s turn. Which position would you like to play at? ");
string? input = Console.ReadLine();
bool isNumerical = int.TryParse(input, out int _);
while (!isNumerical)
{
Console.Write("Invalid input, please input a number. ");
input = Console.ReadLine();
isNumerical = int.TryParse(input, out int _);
}
return int.Parse(input);
}
public PlayerSymbol SendPlayerSymbol()
{
return PlayerSymbol;
}
}
// Enumerations
enum PlayerSymbol
{
X,
O
}
Right now, the main issue with this code will be inside the Updater class.
I have a VerifyUserHasInputValidNumber(int userInput) method, taking in the number input that the player has taken, and returning a true or false depending on whether it fits a range of being a value between 1-9.
public bool VerifyUserHasInputValidNumber(int userInput)
{
if (userInput >= 0 || userInput <= 10)
{
return false;
} else
{
return true;
}
}
For some reason though, even though I can confirm that the userInput parameter is being inputted correctly (the Console.WriteLine in the 1st line of the method), it will still produce a false and will tell the user that they've inputted an invalid position.
public void RunGame()
{
while (true)
{
GameBoard.DisplayBoard();
int currentPlayer = GameUpdater.SendPlayerTurnInfo();
int playerInput = Players[currentPlayer].GetUserInput(); // THIS IS THE NUMBER THAT'S BEING INPUTTED INTO THE METHOD THAT I'M HAVING AN ISSUE WITH (the VerifyUserHasInputValidNumber(playerInput); method)
bool playerInputtedValidNumber = GameUpdater.VerifyUserHasInputValidNumber(playerInput); // Should be true if I input any number between 1-9.
if (playerInputtedValidNumber)
{
bool playerInputtedUnusedNumber = GameUpdater.VerifyUserHasInputUnusedSpot(GameBoard.SendBoardPiecesData(--playerInput));
if (playerInputtedUnusedNumber)
{
PlayerSymbol currentPlayerSymbol = Players[currentPlayer].SendPlayerSymbol(); // The symbol of the current player.
GameBoard.UpdateBoardPiecesData(playerInput, currentPlayerSymbol);
}
else
{
Console.WriteLine("This position has already been used!");
continue;
}
}
else
{
Console.WriteLine("Inputted an invalid position!"); // THIS, however, is what is being logged into the console.
continue;
}
}
}
I don't know if it may be a memory leak issue, or if I may have some sort of incorrect formatting, but if I could get any help with this issue, I would greatly appreciate it.
this test
if (userInput >= 0 || userInput <= 10)
is always true. What value do you think will be false?
I assume you want
if (userInput >= 0 && userInput <= 10)
return true;
else return false;

C# Poker: how to keep track of players and make game engine (classes) preflop, flop, turn, river?

Im recently studying c# and want to create a 'simple' console app poker game.
Ive created classes: player, hand, deck, dealer. Dealer gets cards out of the deck and assigns it to player instances. What I'm struggling with now is how to progress further? I need to make some gameplay possible.
This is what i have coded thusfar:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
//Deck d = new Deck();
Player[] players = new Player[2];
Dealer dealer = new Dealer();
players[0] = new Player("M");
players[1] = new Player("T");
foreach (var player in players)
{
Console.WriteLine(player.name);
}
Console.WriteLine();
foreach (var player in players)
{
player.AddCardsToHand(dealer);
}
Console.WriteLine("View hand van player 1");
foreach (string card in players[0].ViewHandCards())
{
Console.WriteLine(card);
}
Console.WriteLine();
Console.WriteLine("View hand van player 2");
foreach (string card in players[1].ViewHandCards())
{
Console.WriteLine(card);
}
Console.WriteLine();
Console.WriteLine("Number of players instantiated:");
Console.WriteLine(Player.playerCount);
Console.WriteLine();
Console.WriteLine("Number of hands instantiated:");
Console.WriteLine(Hand.handCount);
Console.WriteLine();
dealer.SetMoneyAmount(players[0]);
dealer.SetMoneyAmount(players[1], 150);
Console.WriteLine("Money player 1:");
Console.WriteLine(players[0].MoneyAmount);
Console.WriteLine();
Console.WriteLine("Money player 2:");
Console.WriteLine(players[1].MoneyAmount);
Console.WriteLine();
int index = 0;
dealer.SetDealer(players[index]);
Console.WriteLine("Dealer: " + dealer.GetDealer());
// how to know in a class how many players there are and there values?
// create a class containing the players array?
}
}
class Settings
{
// static string dealer;
public static int dealerIndex;
public static string dealerName;
public
}
class User
{
public string name;
}
class Player : User
{
Hand h = new Hand();
public static int playerCount;
private double moneyAmount;
public bool dealerButton;
public double MoneyAmount
{
get
{
return moneyAmount;
}
set
{
moneyAmount = value;
}
}
public int NumOfCardsInHand()
{
return h.cardsInHand;
}
public string[] ViewHandCards()
{
return h.handCards;
}
public void AddCardsToHand(Dealer d)
{
d.DealCard(h);
d.DealCard(h);
}
public Player(string n)
{
this.name = n;
playerCount++;
}
}
class Hand
{
public static int handCount;
public int cardsInHand = 0;
public string[] handCards = new string[2];
public Hand()
{
handCount++;
}
}
class Dealer
{
Deck d = new Deck();
//public void StartGame()
//{
//}
public void DealCard(Hand h)
{
if (h.cardsInHand < 2)
{
if (h.cardsInHand == 0)
h.handCards[0] = d.NextCard();
if (h.cardsInHand == 1)
h.handCards[1] = d.NextCard();
h.cardsInHand++;
}
else
{
Console.WriteLine("Meer dan 2 kaarten per hand is niet toegestaan");
}
}
public void SetMoneyAmount(Player p, double amount = 100)
{
p.MoneyAmount = amount;
}
public void SetDealer(Player p)
{
p.dealerButton = true;
Settings.dealerName = p.name;
}
public string GetDealer()
{
return Settings.dealerName;
}
}
class Deck
{
public int numOfCards = 52;
public string[] cards = new string[13];
public string[] playingCards = new string[52];
public string[] cardsDealt = new string[52];
Random r = new Random();
int y = 0;
public string NextCard()
{
string nextCard = "-";
int x = 0;
while (x < 1)
{
nextCard = playingCards[r.Next(0, playingCards.Length)];
if (!cardsDealt.Contains(nextCard))
{
cardsDealt[y] = nextCard;
y++;
x++;
}
else
{
Console.WriteLine("Reeds gedeelde kaart bijna opnieuw gedeeld!");
x = 0;
}
}
return nextCard;
}
public void ConstructDeck()
{
// spade club heart diamond
this.cards[0] = "A";
this.cards[1] = "K";
this.cards[2] = "Q";
this.cards[3] = "J";
this.cards[4] = "10";
this.cards[5] = "9";
this.cards[6] = "8";
this.cards[7] = "7";
this.cards[8] = "6";
this.cards[9] = "5";
this.cards[10] = "4";
this.cards[11] = "3";
this.cards[12] = "2";
int x = 0;
foreach (string card in this.cards)
{
this.playingCards[x] = card + "s";
x++;
this.playingCards[x] = card + "c";
x++;
this.playingCards[x] = card + "h";
x++;
this.playingCards[x] = card + "d";
x++;
}
}
public Deck()
{
ConstructDeck();
}
}
class Bet
{
public double betAmount;
public Bet(Player p, double betInput)
{
betAmount = betInput;
}
}
}
I have put the player instances in an array and can call them like this players[0] (player 1).
I would like to know if im on the right track here and more specifically how do I keep track of the players I instantiated so that other classes can access the player instance variables? Im assigning one player the dealer status and would need to know where to start asking for other players initiative in the game like needing to bet call check or fold at some given point. I dont know what kind of classes I would need to create for a preflop game, a flop game, a turn game and the river game. Classes for each game name? How would I check if a player finished his action?
I think I should create a class like: preflopgame and identify the dealer than ask initiative (bet fold etc (make classes of betting folding checking etc) of the player thats not the dealer and keep track via a variable that player finished its initiative in the preflopgame class? And if preflopgame is played out: some kind of static boolean field in the class indicating its finished. Than move on to the next game: flopgame. Is this the right way of thinking about this game?
Any suggestions would certainly be much apreciated.
Excuse my English im Dutch from origin.

declaring new objects with GUI in C#

So I am using a GUI with a class. I have done it before and I know most of the time you create an event for a button. Then when that button is pushed, you can create a new object. In this project I am working on, I have a TextBox that I type a name and a score into. Then when I hit the enter button that I have, I want to create a new object with the parameterized constructor and place the name and score in different arrays so I can manipulate them. Then I want to produce the highest, lowest, and avg scores. I have had previous projects where I just create a new object when the button is pressed. But with this I am loading in multiple things in the same TextBox. So every time the button was hit I was creating a new object. What I want to do is create the object once with a parameterized constructor and then add the names and scores to arrays within the class. Any suggestions.
The bottom method in my form class I tried to mess around and do it this way, but it wouldn't do anything.
private void nameTextBox_TextChanged(object sender, EventArgs e)
{
//Get the information from the text box and store it in a variable
string userInput = nameTextBox.Text;
//Create a new object with the parameterized constructor
myBowlingTeam = new BowlingTeam(userInput);
}
PLEASE HELP. This is like my only hiccup. If I get this part to work right the program will work. Cause I know how to work with the class to produce the results I want. Thanks in advance.
Here is my class code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project_9
{
class BowlingTeam
{
const int MAX = 10;
//local variables
int sizeOfName = 0;
int sizeOfScore = 0;
//Declare Private Data Members
private string nameAndScore = "";
private string name = "";
private int score = 0;
private string[] nameArray = new string[MAX];
private int[] scoreArray = new int[MAX];
private string[] nameAndScoreArray = new string[MAX];
//Default Constructor
//Purpose: To set the initial values of an object
//Parameters: None
//Returns: Nothing
public BowlingTeam()
{
nameAndScore = "";
name = "";
score = 0;
for(int i = 0; i < MAX; i++)
{
nameArray[i] = "";
}
for(int i = 0; i < MAX; i++)
{
scoreArray[i] = 0;
}
for (int i = 0; i < MAX; i++)
{
nameAndScoreArray[i] = "";
}
}
//Parameterized Constructor
//Purpose: To set the values of an object
//Parameters: None
//Returns: Nothing
public BowlingTeam(string aString)
{
nameAndScore = aString;
name = "";
score = 0;
for (int i = 0; i < MAX; i++)
{
nameArray[i] = "";
}
for (int i = 0; i < MAX; i++)
{
scoreArray[i] = 0;
}
for (int i = 0; i < MAX; i++)
{
nameAndScoreArray[i] = "";
}
}
//Split the Input Method
//Purpose: To Split up the data in the array
//Parameters: An array of strings
//Returns: Nothing
public void SplitAndDisperseArray()
{
nameAndScoreArray = nameAndScore.Split();
name = nameAndScoreArray[0];
score = int.Parse(nameAndScoreArray[1]);
//Place the name and the score in their one arrays
PlaceInNameArray(name);
PlaceInScoreArray(score);
}
//Find Highest Score Method
//Purpose: To find the highest score
//Parameters: An array of int
//Returns: An int
public int CalcHighestScore()
{
int highestScore = 0;
int size = 0;
for (int i = 0; i < MAX; i++ )
{
if (scoreArray[i] < scoreArray[i + 1])
{
highestScore = scoreArray[i];
}
else
{
highestScore = scoreArray[i + 1];
}
}
return highestScore;
}
//Find Lowest Score Method
//Purpose: To find the lowest score
//Parameters: An array of int
//Returns: An int
public int CalcLowestScore(int[] anArrayOfInts, int sizeOfArray)
{
int lowestScore = 0;
while (sizeOfArray < MAX)
{
if (anArrayOfInts[sizeOfArray] < anArrayOfInts[sizeOfArray + 1])
{
lowestScore = anArrayOfInts[sizeOfArray];
}
else
{
lowestScore = anArrayOfInts[sizeOfArray + 1];
}
}
return lowestScore;
}
//Calulate Avg. Score Method
//Purpose: To calculate the avg score
//Parameters: An array of int
//Returns: An double
public double CalculateAvgScore(int[] anArrayOfInts, int sizeOfArray)
{
int sum = 0;
double avg = 0;
//Add up all of the elements in the array
while(sizeOfArray < MAX)
{
sum += anArrayOfInts[sizeOfArray];
}
//Divide the sum by the size of the array
return avg /= sum;
}
//Set Score Array Method
//Purpose: To put scores in the score array
//Parameters: An int
//Returns: Nothing
public void PlaceInScoreArray(int aScore)
{
scoreArray[sizeOfScore] = score;
sizeOfScore++;
}
//Set Name Array Method
//Purpose: To put names in the names array
//Parameters: A string
//Returns: Nothing
public void PlaceInNameArray(string aName)
{
nameArray[sizeOfName] = name;
sizeOfName++;
}
}
}
Here is my Form1 code for the GUI:
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 Project_9
{
public partial class Form1 : Form
{
//Declare a reference variable to the class
private BowlingTeam myBowlingTeam;
public Form1()
{
InitializeComponent();
myBowlingTeam = new BowlingTeam();//Create a BowlingTeam object with the default constructor
}
//ExitToolStripMenuItem1_Click
//Purpose: To close the application when clicked
//Parameters: The sending object and the event arguments
//Returns: nothing
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
//AboutToolStripMenuItem1_Click
//Purpose: To display student information
//Parameters: The sending object and the event arguments
//Returns: nothing
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Charlie Barber\nCS 1400-X01\nProject 9");
}
//Enter Button Clicked
//Purpose: To store the info in an array when the button is pressed
//Parameters: The sending object and the event arguments
//Returns: nothing
private void button1_Click(object sender, EventArgs e)
{
//Get the information from the text box and store it in a variable
string userInput = nameTextBox.Text;
if (userInput != "")
{
//Create a new object with the parameterized constructor
// myBowlingTeam = new BowlingTeam(userInput);
//Split the string into two separte pieces of data
myBowlingTeam.SplitAndDisperseArray();
//Clear the text box
nameTextBox.Clear();
}
else
{
int highestScore = myBowlingTeam.CalcHighestScore();
}
}
//Nothing
private void nameTextBox_TextChanged(object sender, EventArgs e)
{
//Get the information from the text box and store it in a variable
string userInput = nameTextBox.Text;
//Create a new object with the parameterized constructor
myBowlingTeam = new BowlingTeam(userInput);
}
}
What is stopping you from using a class for the players inside the team? Keep the arrays synchronised in your solution seems more trouble than its worth.
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Observable
{
class BowlingTeam
{
public string TeamName { get; set; }
private readonly IList<Player> players = new ObservableCollection<Player>();
public IList<Player> Players
{
get
{
return players;
}
}
public void AddPlayer(string name, int score)
{
AddPlayer(new Player(name, score));
}
public void AddPlayer(Player p)
{
players.Add(p);
}
public Player HighestRanked()
{
if (Players.Count == 0)
{
// no players
return null;
}
int max = 0, index = -1;
for (int i = 0; i < Players.Count; i++)
{
if (Players[i].Score > max)
{
index = i;
max = Players[i].Score;
}
}
if (index < 0)
{
// no players found with a score greater than 0
return null;
}
return Players[index];
}
public BowlingTeam()
{
}
public BowlingTeam(string teamName)
{
this.TeamName = teamName;
}
}
class Player
{
public string Name { get; set; }
public int Score { get; set; }
public Player()
{
}
public Player(string name, int score)
{
this.Name = name;
this.Score = score;
}
public override string ToString()
{
return string.Format("{0} {1:n2}", Name, Score);
}
}
}
which could be manipulated as such
BowlingTeam b1 = new BowlingTeam("SO");
b1.AddPlayer("Player 1", 100);
b1.AddPlayer("Player 2", 135);
b1.AddPlayer("Player 3", 90);
b1.AddPlayer("Player 4", 127);
Console.WriteLine("Highest ranked player: {0}", b1.HighestRanked());
An advantage for later is that you can hang on the OnCollectionChangedEvents of your players, to be notified when players were added/removed.

C# Comparing List objects to passed parameters

What I am trying to do is get the number of right angled triangles between 1 and 20 on both sides.
Most of the logic is fine, but when I want to check for 3, 4 and 5 this is one triangle, while 4, 3 and 5 would not be valid as it 3, 4, 5 in a different order.
Here is the code that I have written for the problem area
public bool isAlreadyValidTriangle(int intAdj, int intOpp, List<Triangle> triangleList)
{
bool breakLoop = false;
Int32 length = triangleList.Count;
for (int index = 0; index < length && breakLoop != false; index++)
{
//This is to compare an existing adjacent that is stored in the list to the
//supplied opposite, this is to prebent the 3, 4, 5 and 4, 3, 5 issue
var response = triangleList.Find(r => r.IntAdjacent == intOpp);
if (response !=null)
{
//This is to compare an existing opposite that is stored in the list to the
//supplied adjacent, this is to prebent the 3, 4, 5 and 4, 3, 5 issue
var otherResponse = triangleList.Find(r => r.IntOpposite == intAdj);
if (otherResponse != null)
{
breakLoop = true;
}
}
}
return breakLoop;
}
Just in case anybody needs the Triangle code, here it is
public class Triangle
{
private int intAdjacent;
private int intOpposite;
private int intHypotenuse;
public Triangle(int intAdjacent, int intOpposite, int intHypotenuse)
{
this.intAdjacent = intAdjacent;
this.intOpposite = intOpposite;
this.intHypotenuse = intHypotenuse;
}
public int IntAdjacent
{
get { return intAdjacent; }
}
public int IntOpposite
{
get { return intOpposite; }
}
public int IntHypotenuse
{
get { return intHypotenuse; }
}
}
Could some one spot to see where I am making a mistake in the logic or have made an error in the code itself?
Keith
You can simplify this quite a lot like this:
public bool isAlreadyValidTriangle(int intAdj, int intOpp, List<Triangle> triangleList)
{
if(triangleList.Any(t => t.IntAdjacent == intAdj && t.IntOpposite == intOpp))
return true;
return triangleList.Any(t => t.IntAdjacent == intOpp && t.IntOpposite == intAdj);
}
It first looks for any matches where the passed in values are a match, then reverses the search if they don't. It's slightly different to your code in that it looks for both adjacent and opposite at the same time which is where you went wrong. Additionally, it uses Any which returns a boolean value if any item is found that matches.
Thinking about this further, I would change the function to make it an extension method like this:
public static bool isAlreadyValidTriangle(this List<Triangle> triangleList, int intAdj, int intOpp)
{
if(triangleList.Any(t => t.IntAdjacent == intAdj && t.IntOpposite == intOpp))
return true;
return triangleList.Any(t => t.IntAdjacent == intOpp && t.IntOpposite == intAdj);
}
This means you can call it with a little more readability:
List<Triangle> triangleList = new List<Triangle>();
... fill list with triangles ...
if(triangleList.isAlreadyValidTriangle(adjacent, opposite)
{
...
}
First of all thanks for the advice and help.
Here is the complete code from start to finish
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ConsoleApplication1
{
public class Program
{
private static double doubleHypotenuse = 0;
private static int adjacent = 1;
private static int opposite = 1;
private static int limit = 200;
private static int count = 0;
public static void Main(string[] args)
{
TriangleLogic triLogic = new TriangleLogic();
List<Triangle> triangleList = new List<Triangle>();
List<Triangle> trianglePlus1 = new List<Triangle>();
while (adjacent < limit)
{
opposite = 1;
while (opposite < limit)
{
doubleHypotenuse = triLogic.intRightAngle(adjacent, opposite);
if (doubleHypotenuse % 1 == 0)
{
if (!triLogic.isAlreadyValidTriangle(adjacent, opposite, triangleList))
{
triangleList.Add(new Triangle(adjacent, opposite, (int)Convert.ToInt32(doubleHypotenuse)));
}
count++;
}
opposite++;
}
adjacent++;
}
Console.WriteLine("The following are integer triangles");
triangleList.ForEach(delegate(Triangle pytag)
{
if ((pytag.IntHypotenuse - pytag.IntOpposite) == 1)
{
trianglePlus1.Add(new Triangle(pytag.IntAdjacent, pytag.IntOpposite, pytag.IntHypotenuse));
}
Console.WriteLine(pytag.IntAdjacent + ", " + pytag.IntOpposite + " and " + pytag.IntHypotenuse);
});
Console.WriteLine("the number of squares is " + count);
Int32 length = triangleList.Count;
Console.WriteLine("the length of the list is " + length);
Console.WriteLine("");
Console.WriteLine("the List of triangles with the hypotenuse 1 ");
Console.WriteLine("more than the opposite");
trianglePlus1.ForEach(delegate(Triangle pytagPlus1)
{
Console.WriteLine(pytagPlus1.IntAdjacent + ", " + pytagPlus1.IntOpposite + " and " + pytagPlus1.IntHypotenuse);
});
Int32 lengthPlus1 = trianglePlus1.Count;
Console.WriteLine("the length of the list is " + lengthPlus1);
}
}
}
Here is the Triangle Class
public class Triangle
{
private int intAdjacent;
private int intOpposite;
private int intHypotenuse;
public Triangle(int intAdjacent, int intOpposite, int intHypotenuse)
{
this.intAdjacent = intAdjacent;
this.intOpposite = intOpposite;
this.intHypotenuse = intHypotenuse;
}
public int IntAdjacent
{
get { return intAdjacent; }
}
public int IntOpposite
{
get { return intOpposite; }
}
public int IntHypotenuse
{
get { return intHypotenuse; }
}
}
And finally the TriangleLogic class
public class TriangleLogic
{
private double squareAdjacent = 0;
private double squareOpposite = 0;
private double squareSum = 0;
public TriangleLogic()
{
}
public double intRightAngle(int intAdjacent, int intOpposite)
{
squareAdjacent = Math.Pow(Convert.ToDouble(intAdjacent), 2);
squareOpposite = Math.Pow(Convert.ToDouble(intOpposite), 2);
squareSum = squareAdjacent + squareOpposite;
return Math.Sqrt(squareSum);
}
public bool isAlreadyValidTriangle(int intAdj, int intOpp, List<Triangle> triangleList)
{
if (triangleList.Any(t => t.IntAdjacent == intAdj && t.IntOpposite == intOpp))
return true;
return triangleList.Any(t => t.IntAdjacent == intOpp && t.IntOpposite == intAdj);
}
}
Thanks again for the support

Check if permutations of characters are contained in text file

Quick question.
I am writing a program to find all the permutations of a set of characters I input into the application.
This part works perfectly.
My problem is that I need to check all the permutations of the characters against a text file I use as a dictionary.
Ex. If I input the characters TSTE the outputs givin are tset,ttse,ttes,tets,test,stte,stet,sett...
I only want to print the valid words like tset,sett,stet,test,tets. where ttse,ttes,stte is not printed.
The code I have so far is as follows.
I have been scracthing at the edges of my scull for the past few days and just cant seem to find a way to do it.
Please if there is anything you can see that I have missed?
Thank you
static void Main(string[] args)
{
Console.BufferHeight = Int16.MaxValue - 1;
Console.WindowHeight = 40;
Console.WindowWidth = 120;
Permute p = new Permute();
var d = Read();
string line;
string str = System.IO.File.ReadAllText("Dictionary.txt");
while ((line = Console.ReadLine()) != null)
{
char[] c2 = line.ToArray();
p.setper(c2);
}
}
static Dictionary<string, string> Read()
{
var d = new Dictionary<string, string>();
using (StreamReader sr = new StreamReader("Dictionary.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string a = Alphabet(line);
string v;
if (d.TryGetValue(a, out v))
{
d[a] = v + "," + line;
}
else
{
d.Add(a, line);
}
}
}
return d;
}
static string Alphabet(string s)
{
char[] a = s.ToCharArray();
Array.Sort(a);
return new string(a);
}
static void Show(Dictionary<string, string> d, string w)
{
string v;
if (d.TryGetValue(Alphabet(w), out v))
{
Console.WriteLine(v);
}
else
{
Console.WriteLine("-----------");
}
}
}
class Permute
{
private void swap(ref char a, ref char b)
{
if (a == b) return;
a ^= b;
b ^= a;
a ^= b;
}
public void setper(char[] list)
{
int x = list.Length - 1;
go(list, 0, x);
}
public void go(char[] list1, int k, int m)
{
if (k == m)
{
Console.WriteLine(list1);
Console.WriteLine(" ");
}
else
{
for (int i = k; i <= m; i++)
{
swap(ref list1[k], ref list1[i]);
go(list1, k + 1, m);
swap(ref list1[k], ref list1[i]);
}
}
}
you just missed Show(d, line); i loop.
change like this.
while ((line = Console.ReadLine()) != null)
{
char[] c2 = line.ToArray();
p.setper(c2);
Console.WriteLine(" combinations which are in Dictionary are:");
Show(d, line);
}
then ..
you didn't required dictionary
use List<string> Dic=new List<string>();// declare it in globally
Dic.add(line); //each line in dictionary
before printing each word
if(Dic.contains(word))
print it;
else{ //no printing }
Not possible with current state.
It's possible because
If the "dictionary.txt" was your input, then you did not define what are the valid words.
You at leaset need another dictionary to define those valid words or an algorithm to decide what those are and what those are not.
If the input is from UI and "dictionary.txt" is the defined valid words, you don't need to the permute the input, just search the input from "dictionary.txt".
However, your Read method is improvable, like
static Dictionary<String, String> Read(String path) {
return (
from line in File.ReadAllLines(path)
where false==String.IsNullOrEmpty(line)
group line by Alphabet(line) into g
select
new {
Value=String.Join(",", g.ToArray()),
Key=g.Key
}
).ToDictionary(x => x.Key, x => x.Value);
}
Although for the valid words are as I mentioned in another answer, not possible with your current state, I've make the code pretty clear for you.
It finally the code, is separated in three parts. They are Permutable<T>, ConsoleHelper and the ConsoleApplication1.Program with an utility Permutation class.
Permutable<T> (Permutable.cs)
using System.Collections.Generic;
using System.Collections;
using System;
public partial class Permutable<T>: IEnumerable {
public static explicit operator Permutable<T>(T[] array) {
return new Permutable<T>(array);
}
static IEnumerable Permute<TElement>(IList<TElement> list, int depth, int count) {
if(count==depth)
yield return list;
else {
for(var i=depth; i<=count; ++i) {
Swap(list, depth, i);
foreach(var sequence in Permutable<T>.Permute(list, 1+depth, count))
yield return sequence;
Swap(list, depth, i);
}
}
}
static void Swap<TElement>(IList<TElement> list, int depth, int index) {
var local=list[depth];
list[depth]=list[index];
list[index]=local;
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
public IEnumerator<IList<T>> GetEnumerator() {
var list=this.m_List;
if(list.Count>0)
foreach(IList<T> sequence in Permutable<T>.Permute(list, 0, list.Count-1))
yield return sequence;
}
protected Permutable(IList<T> list) {
this.m_List=list;
}
IList<T> m_List;
}
ConsoleHelper (ConsoleHelper.cs)
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public static partial class ConsoleHelper {
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public static explicit operator Rectangle(RECT rect) {
return new Rectangle {
X=rect.Left,
Y=rect.Top,
Width=rect.Right-rect.Left,
Height=rect.Bottom-rect.Top
};
}
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", SetLastError=true)]
static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool repaint);
[DllImport("user32.dll", SetLastError=true)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr GetConsoleWindow();
public static void CenterScreen() {
RECT rect;
var hWnn=ConsoleHelper.GetConsoleWindow();
var workingArea=Screen.GetWorkingArea(Point.Empty);
ConsoleHelper.GetWindowRect(hWnn, out rect);
var rectangle=(Rectangle)rect;
rectangle=
new Rectangle {
X=(workingArea.Width-rectangle.Width)/2,
Y=(workingArea.Height-rectangle.Height)/2,
Width=rectangle.Width,
Height=rectangle.Height
};
ConsoleHelper.MoveWindow(
hWnn,
rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height,
true
);
}
}
ConsoleApplication1.Program & Permutation (Program.cs)
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public partial class Permutation {
public static Permutation FromFile(String path) {
return new Permutation(path);
}
public static String GetSortedAlphabet(String text) {
var array=text.ToArray();
Array.Sort(array);
return new String(array);
}
public Dictionary<String, String> Dictionary {
private set;
get;
}
public FileInfo SourceFile {
private set;
get;
}
public Permutation(String path) {
this.Dictionary=(
from line in File.ReadAllLines(path)
where false==String.IsNullOrEmpty(line)
group line by Permutation.GetSortedAlphabet(line) into g
select
new {
Value=String.Join(", ", g.Distinct().ToArray()),
Key=g.Key
}
).ToDictionary(x => x.Key, x => x.Value);
this.SourceFile=new FileInfo(path);
}
}
namespace ConsoleApplication1 {
partial class Program {
static void ProcessLine(IList<char> input) {
Console.WriteLine();
if(input.Count>0) {
var inputArray=input.ToArray();
var key=Permutation.GetSortedAlphabet(new String(inputArray));
var dict=Program.Permutation.Dictionary;
var hasKey=dict.ContainsKey(key);
var source=Permutation.SourceFile;
Console.WriteLine("Possible permutations are: ");
foreach(var sequence in (Permutable<char>)inputArray)
Console.WriteLine("{0}", new String(sequence.ToArray()));
Console.WriteLine("Acceptable in file '{0}' are: ", source.FullName);
Console.WriteLine("{0}", hasKey?dict[key]:"<none>");
Console.WriteLine();
input.Clear();
}
Console.Write(Prompt);
}
static void ProcessChar(IList<char> input, char keyChar) {
Console.Write(keyChar);
input.Add(keyChar);
}
static void ProcessExit(IList<char> input, char keyChar) {
Console.WriteLine();
Console.Write("Are you sure to exit? (Press Esc again to exit)");
input.Add(keyChar);
}
static bool ProcessLast(IList<char> input, char keyChar) {
var last=input.Count-1;
if(0>last||input[last]!=(char)ConsoleKey.Escape)
return false;
input.Clear();
return true;
}
public static Permutation Permutation {
private set;
get;
}
public static String Prompt {
private set;
get;
}
}
partial class Program {
static void Main(String[] args) {
Console.BufferHeight=short.MaxValue-1;
Console.SetWindowSize(120, 40);
ConsoleHelper.CenterScreen();
var input=new List<char>(char.MaxValue);
Program.Permutation=Permutation.FromFile(#"c:\dictionary.txt");
Program.Prompt="User>\x20";
Program.ProcessLine(input);
for(; ; ) {
var keyInfo=Console.ReadKey(true);
var keyChar=keyInfo.KeyChar;
var keyCode=keyInfo.Key;
if(ConsoleKey.Escape==keyCode) {
if(Program.ProcessLast(input, keyChar))
break;
Program.ProcessExit(input, keyChar);
continue;
}
if(ConsoleKey.Enter==keyCode) {
Program.ProcessLine(input);
continue;
}
if(default(ConsoleModifiers)!=keyInfo.Modifiers)
continue;
if(0x1f>keyChar||keyChar>0x7f)
continue;
if(Program.ProcessLast(input, keyChar))
Console.WriteLine();
Program.ProcessChar(input, keyChar);
}
}
}
}
The ConsoleHelper class is only use for ceteral your resized console window, that you can test the program more comfortable. The Permutable class is what I fully re-designed from your original class; it now come with IEnumerable to permute, and also a generic class.
The Permutation class, is like a utility class, itself provide a FromFile method as your original Read, and stores the Dictionary<String, String> as a property. The original method Alphabet is renamed GetSortedAlphabet for more semantical.
The Program class has four main static ProcessXXX methods, they are
ProcessChar: processes for a char of the range from 0x20 to 0x7f
ProcessLine: processes for Enter pressed
ProcessExit: processes for Excape pressed
ProcessLast: additional processing for ProcessLine and ProcessExit
Yes, I meant to make them have the same length of name. For more, Program class have two static properties; Permutation for storing a instance of class Permutation, and Prompt is a string for prompting user.
When your input is not defined in "c:\dictionary.txt", the prompt of "Acceptable in file .." will get you "<none>".
The exit command is twice-Escape key press, you would see
Are you sure to exit? (Press Esc again to exit)
and if you press Enter or other keys, it back to the initial state.
That's all. Now it's time to discover the finally problem you've encountered. After you test with this program, you might describe you questions and issues more clearly.
Good luck!
Thank you for all your feedback.
I have finally figured it out and found a solution to the problem I was having.
static void Main(string[] args)
{
Console.BufferHeight = Int16.MaxValue - 1;
Console.WindowHeight = 40;
Console.WindowWidth = 120;
Console.WriteLine("Enter your caracters for the anagram: ");
//var d = Read();
string line;
//string DictionaryInput = System.IO.File.ReadAllText("Dictionary.txt");
while ((line = Console.ReadLine()) != null)
{
Console.WriteLine("Your results are: ");
char[] charArray = line.ToArray();
//Show(d, line); //Using this to check that words found are the correct words in the dictionary.
setper(charArray);
Console.WriteLine("-----------------------------------------DONE-----------------------------------------");
Console.WriteLine("Enter your caracters for the anagram: ");
File.Delete("Permutations.txt");
}
}
static void swap(ref char a, ref char b)
{
if (a == b) return;
a ^= b;
b ^= a;
a ^= b;
}
static void setper(char[] list)
{
int x = list.Length - 1;
permuteWords(list, 0, x);
}
static void permuteWords(char[] list1, int k, int m)
{
if (k == m)
{
StreamWriter sw = new StreamWriter("Permutations.txt", true);
sw.WriteLine(list1);
sw.Close();
Regex permutationPattern = new Regex(new string(list1));
string[] permutations = File.ReadAllLines("Permutations.txt");
Regex pattern = new Regex(new string(list1));
string[] lines = File.ReadAllLines("Dictionary.txt");
foreach (string line in lines)
{
var matches = pattern.Matches(line);
if (pattern.ToString() == line)
{
Console.WriteLine(line);
}
}
}
else
{
for (int i = k; i <= m; i++)
{
swap(ref list1[k], ref list1[i]);
permuteWords(list1, k + 1, m);
swap(ref list1[k], ref list1[i]);
}
}
}

Categories

Resources