Save and load a game by using StreamWriter and ReadWriter (C#) - c#

I'm creating a small program which can save and load char array values. Then, I got stuck with two problems.
I have no idea how to make the program end after saving the data.
After loading the char array, it looks the game starts where I saved last time. However, when I put "#" on the place where is already marked, it is accepted. (It is supposed to display error message)
This is when I start new game.
It displays error message properly.
Here is class which includes streamWriter and streamReader.
public class History
{
public char QUIT = 'Y';
public char CONTINUE = 'N';
public char inputGameContinue;
public void WriteFile(char []arr)
{
FileStream sb = new FileStream("MyFile.txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(sb);
WriteLine("If you want to save the data, enter" + QUIT +"| To continue, enter "+CONTINUE );
inputGameContinue = char.Parse(ReadLine());
if(inputGameContinue=='Y')
{
sw.Write(arr);
WriteLine("The data is saved!");
}
sw.Close();
}
public void ReadFile()
{
string path = "MyFile.txt";
WriteLine("New game? >> 1 | Load saved data? >>2 ");
int command = int.Parse(ReadLine());
if (command == 2)
{
using (StreamReader sr = new StreamReader(path))
{
while (sr.Peek() >= 0)
{
WriteLine(sr.ReadLine());
}
}
}
}
}
Class2
using System;
using static System.Console;
using System.IO;
namespace createSample
{
public class writeRead
{
public static void Main(string[] args)
{
InputClass inputClass = new InputClass();
ArrayValue arrayValue = new ArrayValue();
History history = new History();
WriteLine("Welcome to game!");
WriteLine("");
history.ReadFile();
do
{
inputClass.inputNumber();
while (true)
{
if (arrayValue.arr[inputClass.input] == '#')
{
WriteLine("{0} already marked '#'. Try another.", inputClass.input);
inputClass.inputNumber();
}
else
{
arrayValue.arr[inputClass.input] = '#';
arrayValue.printArray();
history.WriteFile(arrayValue.arr);
break;
}
}
}
while (checkWhenFinish(arrayValue)!=1 );
WriteLine("All letters are marked with '#'");
Read();
}
public static int checkWhenFinish(ArrayValue a)
{
if(a.arr[0] != '0' && a.arr[1] != '1' && a.arr[2] != '2' && a.arr[3] != '3' && a.arr[4] != '4')
{
return 1;
}
else
{
return 0;
}
}
}
}
Class3
using System;
using System;
using System.Numerics;
using System.Reflection.Emit;
using static System.Console;
using System.IO;
namespace createSample
{
public class ArrayValue
{
public char []arr = { '0','1', '2', '3', '4' };
public void printArray()
{
WriteLine("{0},{1},{2},{3},{4}", arr[0], arr[1], arr[2], arr[3], arr[4]);
}
}
}
Class 4
using System;
using System;
using System.Numerics;
using System.Reflection.Emit;
using static System.Console;
using System.IO;
namespace createSample
{
public class InputClass
{
public int input;
public void inputNumber()
{
while (true)
{
Write("Enter number ? (0 to 4) >> ");
if (!int.TryParse(ReadLine(), out input))
{
input = -1;
}
if (input == 0|| input == 1 || input == 2 || input == 3 || input == 4 )
{
break;
}
else
{
WriteLine("Error! Try again!");
}
}
}
}
}

The problem is when you call history.ReadFile() it can read the file and display its contents, but it never updates arrayValue.arr so when the check is done later, arrayValue.arr[inputClass.input] is still 2.
You might want to pass in arrayValue by reference to ReadFile() to have it updated:
history.ReadFile(ref arrayValue);
then in History
public void ReadFile(ref ArrayValue arrayValue)
{
...
while (sr.Peek() >= 0)
{
var line = sr.ReadLine();
WriteLine(line);
for (int i = 0; i < arrayValue.arr.Length; i++)
{
arrayValue.arr[i] = line[i];
}
}
...
}

Related

How do I remove the input halt to automate the input?

So basically the program does what it is supposed to do. The two patterns have to be split with an open line. But I did something wrong now the input wont go in smoothly. I have to press enter a couple of times. The Expected input is:
...........*........
....*.....*.........
.........*..*...*...
*..*..*......***....
..*.....*...........
.*..................
.......*.........*.*
....................
.....*............*.
..........
.*.**.*...
*....*.*.*
..........
..*.....*.
and Output should be
...................*
.................**.
..............***...
........******......
......**............
.....*..............
..***...............
....................
**..................
..........
......****
..****....
..........
**........
But mine looks like this
...........*........
....*.....*.........
.........*..*...*...
*..*..*......***....
..*.....*...........
.*..................
.......*.........*.*
....................
.....*............*.
...................*
.................**.
..............***...
........******......
......**............
.....*..............
..***...............
....................
**..................
..........
.*.**.*...
*....*.*.*
..........
..*.....*.
......****
..****....
..........
**........
I have to press enter a couple of times to get this.
My Code looks like this
using System;
using System.Runtime.CompilerServices;
using Microsoft.VisualBasic;
using System.Collections.Generic;
using System.Linq;
public class Program
{
static void defragDisk(Queue<string> diskLine) // Method that will move all the Starsto the right
{
int lnLength = 0;
int iIndex = 0;
int iStars = 0;
int iTotalStars = 0;
while (diskLine.Count > 0)
{
var line = diskLine.Dequeue();
lnLength = line.Length;
iIndex = lnLength - 1 - iTotalStars;
iStars = line.Count(x => x == '*');
iTotalStars += iStars;
var rangeFrom = iIndex - iStars + 1;
var availableIndexes = Enumerable.Range(rangeFrom, iStars).ToDictionary(x => x);
for (int i = 0; i < lnLength; i++)
{
if (availableIndexes.ContainsKey(i))
Console.Write("*");
else
Console.Write(".");
}
Console.Write("\n");
}
}
static void populateQueue(Queue<string> diskLine) // I am using a queue as the sizes can vary without indication
{
bool bCompleted = false;
while (!bCompleted)
{
var line = Console.ReadLine();
if (line == "")
{
bCompleted = true;
break;
}
else
{
diskLine.Enqueue(line);
}
}
}
public static void Main()
{
bool bCompleted = false;
Queue<string> diskLine = new Queue<string>();
while (!bCompleted)
{
populateQueue(diskLine);
defragDisk(diskLine);
diskLine.Clear();
if (Console.ReadLine() == "")
{
bCompleted = true;
break;
}
}
}
}

Problem with button CreatePrizeButton_Click

When I start the program, unfortunately, after not entering data and pressing the "Create Prize" button, I do not receive the message "This form contains incorrect information. Please check and try again." What am I doing wrong?
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 TrackerLibrary;
namespace TrackerUI
{
public partial class CreatePrizeForm : Form
{
public CreatePrizeForm()
{
InitializeComponent();
}
private void CreatePrizeButton_Click(object sender, EventArgs e)
{
if (ValidateForm())
{
PrizeModel model = new PrizeModel(
placeNameValue.Text,
placeNumberValue.Text,
prizeAmountValue.Text,
prizePercentageValue.Text);
foreach (IDataConnection db in GlobalConfig.Connections)
{
db.CreatePrize(model);
}
}
else
{
MessageBox.Show("Ten formularz zawiera błędne informacje. Proszę sprawdzić i spróbować ponownie.");
}
}
private bool ValidateForm()
{
bool output = true;
int placeNumber = 0;
bool placeNumberValidNumber = int.TryParse(placeNumberValue.Text, out placeNumber);
if (placeNumberValidNumber == false)
{
output = false;
}
if (placeNumber < 1)
{
output = false;
}
if (placeNameValue.Text.Length == 0)
{
output = false;
}
decimal prizeAmount = 0;
int prizePercentage = 0;
bool prizeAmountValid = decimal.TryParse(prizeAmountValue.Text, out prizeAmount);
bool prizePercentageValid = int.TryParse(prizePercentageValue.Text, out prizePercentage);
if (prizeAmountValid == false || prizePercentageValid == false)
{
output = false;
}
if (prizeAmount <= 0 && prizePercentage <= 0)
{
output = false;
}
if (prizePercentage < 0 || prizePercentage > 100)
{
output = false;
}
return output;
}
}
}
Hi
When I start the program, unfortunately, after not entering data and pressing the "Create Prize" button, I do not receive the message "This form contains incorrect information. Please check and try again." What am I doing wrong?

My values are changing by changing the position of methods

I'm working on c# to make a program for checking vowels,consonants,characters,words and number of sentences using method for each)
. My program is working good but my
problem is changing the places of method where I applied them chance the values.
Here is the program
on method characters I use the method words (whick basically counts the spaces ) same for Consonants
the problem is I need to apply the methods on main accourding to the order I have created them "Words>Sentences>Vowels>Characters>COnsonants"
If I chnage the order I get the wrong answer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Task_Raza_Class
{
class Program
{
static void Main(string[] args)
{
string state;
Console.WriteLine("Enter an Statement / Sentance \nPress Enter to Continue..");
state = Console.ReadLine();
raza task = new raza();
// Words>Sentances>Vowels>Characters>COnsonents
Console.WriteLine("Words"+task.words(state));
Console.WriteLine("No of Sentances"+task.tances(state));
Console.WriteLine("Vowels"+task.vowels(state));
Console.WriteLine("Characters"+task.characters(state));
Console.WriteLine("Consonents"+task.consonents(state));
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Task_Raza_Class
{
class raza
{
public int cw , cv , cc , cp , cchar ;
public raza()
{
cw = 1; cv = cc = cp = cchar = 0;
}
public int words(string state)
{
char[] s_arr = new char[200];
s_arr = state.ToCharArray();
for (int i = 0; i < s_arr.Length; i++)
{
if(s_arr[i]==' ')
{
cw++;
}
}
return (cw);
}
public int tances(string state)
{
char[] s_arr = new char[200];
s_arr = state.ToCharArray();
for (int i = 0; i < s_arr.Length; i++)
{
if (s_arr[i] == '.')
{
cp++;
}
}
return (cp);
}
public int vowels(string state)
{
char[] s_arr = new char[200];
s_arr = state.ToCharArray();
for (int i = 0; i < s_arr.Length; i++)
{
if (s_arr[i] == 'a' || s_arr[i] == 'A' || s_arr[i] == 'e' || s_arr[i] == 'E' || s_arr[i] == 'i' || s_arr[i] == 'I' || s_arr[i] == 'o' || s_arr[i] == 'O' || s_arr[i] == 'u' || s_arr[i] == 'U')
{
cv++;
}
}
return (cv);
}
public int characters(string state)
{
char[] s_arr = new char[200];
s_arr = state.ToCharArray();
cchar = s_arr.Lenght - words(state)-1
return (cchar);
}
public int consonents(string state)
{
char[] s_arr = new char[200];
s_arr = state.ToCharArray();
cc = characters(state)-vowels(state);
return (cc);
}
}
}
The problem is cchar and cv are member fields, whose values are maintained between calls. Because consonents calls characters and vowels, those two functions get called twice and on the 2nd time will have whatever value was left over from the first call. There's no need for any member fields in your raza class - they can all be local variables. Alternatively, you could design raza to accept the state parameter in the constructor, then call characters and consonents and change vowels to reuse the values from cchar and cv.
(BTW the correct English spelling is "consonants" and "sentences")

converting for loop to foreach

So I have this piece of code that works fine, how ever for my assignment the professor wants the code to work with a foreach statment. The only way I could get it to work was with a for loop. Anyone know how to convert the for loop into a foreach statment?
here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CheckZips.cs
{
class Program
{
static void Main(string[] args)
{
int[] zips = new int[10] { 07950, 07840, 07828, 07836, 07928, 07869, 07849, 07852, 07960, 07876 };
int correctZipCode;
int input;
Console.WriteLine("Enter a zip code.");
input = int.Parse(Console.ReadLine());
correctZipCode = Convert.ToInt32(input);
bool found = false;
for (int i = 0; i < zips.Length; ++i)
{
if(correctZipCode == zips[i])
{
found = true;
break;
}
}
if (found)
{
Console.WriteLine("We deliver to that zip code.");
}
else
{
Console.WriteLine("We do not deliver to that zip code.");
}
}
}
}
A foreach can be implemented like this:
foreach (int zip in zips)
{
if (zip == correctZipCode)
{
found = true;
break;
}
}

Removing a line from a text file in C#

i am a newbie in C# and i have a simple console application with method validateVoters() which takes a studentID argument, compares it against text file then return appropriate boolean value.
However i want it to delete that specific studentID if it exists then return true, but there is no generic delete from file method so i used a method recommended by a member here:
Giving me an error with the method in double asterics ** :
Error 2
The name 'RemoveUnnecessaryLine' does not exist in the current context c:\Users\Hlogoyatau\Documents\Visual Studio 2010\Projects\Ijoo\Ijoo\Program.cs 28 43 Ijoo
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace SRCVotingSystem
{
public class Program
{
public bool validateVoter(String cisNo)
{
bool found = false;
try
{
string[] ID = System.IO.File.ReadAllLines(#"C:\Users\Hlogoyatau\Pictures\votersRoll.txt");
foreach (string line in ID)
{
//compares it against text file contents
if (cisNo == line)
{
string[] allLines= File.ReadAllLines("votersRoll.txt");
string[] newIDs= **RemoveUnnecessaryLine**(allLines);
File.WriteAllLines("votersRoll.txt", newIDs);
found = true;
}
}
}
catch (IOException e)
{
Console.WriteLine(e.ToString());
}
return found;
}
public static void Main()
{
Program vv = new Program();
Console.WriteLine(vv.validateVoter("cis11-005"));
}
}
}
/* sample data in text.tx
ID 1 asdfsdaf
ID 2 asdfdsafasdfsadf
ID 3 lkjasdfjsdf
*/
private static void Main(string[] args)
{
var id = 2;
var lines = File.ReadAllLines("C:\\temp\\text.txt");
var remaining = lines.Where(x => !x.Contains(id.ToString())).ToArray();
File.WriteAllLines("C:\\temp\\out.txt", remaining);
}
Try this:
public bool validateVoter(String cisNo)
{
bool found = false;
try
{
string[] ID = System.IO.File.ReadAllLines(#"C:\Users\Hlogoyatau\Pictures\votersRoll.txt");
for (int i = 0; i < ID.Length; i++)
{
string line = ID[i];
//compares it against text file contents
if (cisNo == line)
{
//Shift remaining lines up, overwriting current line
for (int j = i; j < ID.Length - 1; j++)
{
ID[j] = ID[j+1];
}
//Set last line to empty string
ID[ID.Length - 1] = "";
//Write file back to disk
System.IO.File.WriteAllLines(#"C:\Users\Hlogoyatau\Pictures\votersRoll.txt", ID);
found = true;
//Exit loop after something is found
break;
}
}
}
catch (IOException e)
{
Console.WriteLine(e.ToString());
}
return found;
}
It will read the file, and when a match is found, then it shifts the remaining lines up one line. The last line will be cleared, then the file gets written back to disk. If you do not want to have an empty last line, then you can resize the array (see Array.Resize).
Try using LINQ
public void validateVoter(String cisNo)
{
var newIDs = System.IO.File.ReadAllLines(#"C:\Users\Hlogoyatau\Pictures\votersRoll.txt").Where(l => l != cisNo);
File.WriteAllLines(#"C:\Users\Hlogoyatau\Pictures\votersRoll.txt", newIDs);
}

Categories

Resources