my program records the number of bottles four rooms has collected in a bottle drive. When the user types in quit, the number of bottle each room has collected is shown as well a
You can not replace an array easily with individual variables. If you have a declaration like
int room1 = 0, room2 = 0, room3 = 0, room4 = 0;
and want to access room number i
then you have to write
switch (i) {
case 1:
Console.WriteLine(room1);
break;
case 2:
Console.WriteLine(room2);
break;
case 3:
Console.WriteLine(room3);
break;
case 4:
Console.WriteLine(room4);
break;
}
With an array you can simply write
Console.WriteLine(rooms[i]);
If you really want to go this array-less way, I suggest you to use helper methods:
private void SetRoom(int room, int value)
{
switch (room) {
case 1:
room1 = value;
break;
case 2:
room2 = value;
break;
case 3:
room3 = value;
break;
case 4:
room4 = value;
break;
}
}
public int GetRoom(int room)
{
switch (room) {
case 1:
return room1;
case 2:
return room2;
case 3:
return room3;
case 4:
return room4;
default:
return 0;
}
}
You must declare variables room1 to room4 as class members to make this work.
Now you can write:
Console.WriteLine(GetRoom(i));
Or instead of rooms[i] += n;
SetRoom(i, GetRoom(i) + n);
Here's an example that uses a Class to hold the information for each room. The reason for using a class is so that if your program needs to change in the future to collect more information, you won't have to track yet another array, you can just add properties to the class.
The individual rooms are now held in a list instead of an array just to show a different construct.
Here is the new Room class:
public class Room
{
public int Number { get; set; }
public int BottleCount { get; set; }
public Room(int wNumber)
{
Number = wNumber;
}
}
And here is the new version of the program. Note that additional checking of the values entered by the end user has been added in order to prevent exceptions when trying to get the current room or parse to an int the value entered by the user:
static void Main(string[] args)
{
const int MAX_ROOMS = 4;
var cRooms = new System.Collections.Generic.List<Room>();
for (int nI = 0; nI < MAX_ROOMS; nI++)
{
// The room number is 1 to 4
cRooms.Add(new Room(nI + 1));
}
// Initializes the room that wins
//Start of while loop to ask what room your adding into.
while (true)
{
Console.Write("Enter the room you're in: ");
//If user enters quit at anytime, the code will jump out of while statement and enter for loop below
string roomNumber = Console.ReadLine();
if (roomNumber == "quit")
{
//Break statement allows quit to jump out of loop
break;
}
int room = 0;
if (int.TryParse(roomNumber, out room) && (room < MAX_ROOMS) && (room >= 0)) {
Room currentRoom;
currentRoom = cRooms[room];
Console.Write("Bottles collected in room {0}: ", currentRoom.Number);
int wBottleCount = 0;
if (int.TryParse(Console.ReadLine(), out wBottleCount) && (wBottleCount >= 0))
{
// This line adds the count of bottles and records it so you can continuously count the bottles collected.
currentRoom.BottleCount += wBottleCount;
}
else
{
Console.WriteLine("Invalid bottle count; value must be greater than 0");
}
}
else
{
Console.WriteLine("Invalid room number; value must be between 1 and " + MAX_ROOMS.ToString());
}
}
Room maxRoom = null;
foreach (Room currentRoom in cRooms) //This loop goes through the array of rooms (4)
{
// This assumes that the bottle count can never be decreased in a room
if ((maxRoom == null) || (maxRoom.BottleCount < currentRoom.BottleCount))
{
maxRoom = currentRoom;
}
Console.WriteLine("Bottles collected in room {0} = {1}", currentRoom.Number, currentRoom.BottleCount);
}
//Outputs winner
Console.WriteLine("And the Winner is room " + maxRoom.Number + "!!!");
}
You could do that, but that would be a step back from good programming and towards writing bad code.
First it would bloat your code, since you always had to do something like this:
// this is the code you have now (3 lines for 4 rooms):
int room = int.Parse(quit);
Console.Write("Bottles collected in room {0}: ", room);
rooms[room - 1] += int.Parse(Console.ReadLine());
// and this is the code you'll have when you refrain from using arrays
// (17 lines for 2 rooms, ignoring empty lines and ones with only brackets):
int room = int.Parse(quit);
Console.Write("Bottles collected in room {0}: ", room);
switch(room)
{
case 1:
Console.WriteLine(room1);
break;
case 2:
Console.WriteLine(room2);
break;
// other cases...
}
int count = int.Parse(Console.ReadLine());
switch(room)
{
case 1:
room1 += count;
break;
case 2:
room2 += count;
break;
// other cases...
}
And second (and far more important):
The code is totally not extensible. If you want to add a fifth room to collect bottles in, you have to go through the whole program and adjust each and every switch statement, which is not only time consuming but also extremely prone to error.
I think your logic is sound (ie using a variable for the max value and max room and comparing each time). Were there any restriction as to not using arrays? It would seem that using 4 variables would require more lines of code.
I like the answer using a class. But you could very well do this with standard c with an array.
What is the requirement? encapsulation? robustness?