Creating,using and comparing elements within a button collection - c#

I'm making a Tic-tac-toe project, and I'm having some difficulties. I've only gotten a loose grip about collections, so you can see the problem.
Thing is, I created 9 buttons which change their Background image when clicked, and disable themselves. I've managed to make it run for 2 players, but my wish is to create some sort of an AI.
I need a button collection so I can compare their properties, and avoid the usual one-by-one comparison and massive and numerous If statements.
What I actually want is to be able to test whether buttons in the same row or column have the same values (background images). What I've used so far is an array of strings that describes the sign value, but it's entirely detached from the buttons, and it would take a lot of time to type out all that code.
If it cannot be done the way I imagined it, please do tell. I am open to suggestions, and would be most grateful.
Oh, and if you need any code, or further detail, let me know.

You need to separate data (array) and presentation (buttons).
Update
I published a sample console project that compiles and runs.
Its model is separate from presentation so you can take TicTacToe.cs and write a GUI for it.
You don't need strings; booleans are fine for two states.
In fact, there is a third state, which is empty, so you can use a nullable boolean.
So X would correspond to true, O to false, and empty space to null.
I'd create a class that encapsulates a nullable boolean square array:
class TicTacToe {
const int Length = 3;
private bool? [][] _data;
private bool? _winner;
public TicTacToe ()
{
_data = Enumerable
.Range (0, Length)
.Select (_ => new bool? [Length])
.ToArray ();
}
}
Then I'd represent rows, columns and diagonals as vectors:
public bool? GetCell (int row, int column)
{
return _data [row][column];
}
public IEnumerable<bool?> GetRow (int index)
{
return _data [index];
}
IEnumerable<int> GetIndices ()
{
return Enumerable.Range (0, Length);
}
public IEnumerable<bool?> GetColumn (int index)
{
return GetIndices ()
.Select (GetRow)
.Select (row => row.ElementAt (index));
}
public IEnumerable<bool?> GetDiagonal (bool ltr)
{
return GetIndices ()
.Select (i => Tuple.Create (i, ltr ? i : Length - 1 - i))
.Select (pos => GetCell (pos.Item1, pos.Item2));
}
public IEnumerable<IEnumerable<bool?>> GetRows ()
{
return GetIndices ()
.Select (GetRow);
}
public IEnumerable<IEnumerable<bool?>> GetColumns ()
{
return GetIndices ()
.Select (GetColumn);
}
public IEnumerable<IEnumerable<bool?>> GetDiagonals ()
{
return new [] { true, false }
.Select (GetDiagonal);
}
public IEnumerable<IEnumerable<bool?>> GetVectors ()
{
return GetDiagonals ()
.Concat (GetRows ())
.Concat (GetColumns ());
}
Then I'd write a function that takes a vector and says if it's a winning one:
static bool? FindWinner (IEnumerable<bool?> vector)
{
try {
return vector
.Distinct ()
.Single ();
} catch (InvalidOperationException) {
return null;
}
}
static bool? FindWinner (IEnumerable<IEnumerable<bool?>> vectors)
{
return vectors
.Select (FindWinner)
.FirstOrDefault (winner => winner.HasValue);
}
public bool? FindWinner ()
{
return FindWinner (GetVectors ());
}
Now we can call GetWinner to find out if somebody already won.
Then I'd write a method to make a move:
public bool MakeMove (int row, int column, bool move)
{
if (_winner.HasValue)
throw new InvalidOperationException ("The game is already won.");
if (_data [row][column].HasValue)
throw new InvalidOperationException ("This cell is already taken.");
_data [row][column] = move;
_winner = FindWinner ();
return move == _winner;
}
public bool? Winner {
get { return _winner; }
}
This was all inside TicTacToe class.
Your GUI should create it and call its methods.
When a button gets clicked, this is what you may do:
private TicTacToe _game = new TicTacToe ();
private Button [][] _buttons = new Button [][3];
const bool HumanPlayer = true;
const bool AIPlayer = false;
public void HandleButtonClick (object sender, EventArgs e)
{
// Assuming you put a Tuple with row and column in button's Tag property
var position = (Tuple<int, int>) ((Button) sender).Tag;
var row = position.Item1;
var column = position.Item2;
// Sanity check
Debug.Asset (sender == _buttons [row][column]);
bool won = _game.MakeMove (row, column, HumanPlayer);
if (won) {
MessageBox.Show ("You won.");
}
RefreshButtons ();
}
void RefreshButtons ()
{
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
var btn = _buttons [i][j];
var cell = _game.GetCell (i, j);
btn.Enabled = !cell.HasValue;
btn.Text = cell.HasValue
? (cell.Value ? "X" : "O")
: string.Empty;
}
}
}
Your AI should also call MakeMove and do its calculations based on information from calling GetRow, GetColumn and GetDiagonal.
I didn't check the code, it's only a sketch. (But the console project should run just fine.)

What I would use is a game state class that contains the current state of the game. For example:
public class Game
{
// These will have null for unselected, true for circle, false for cross, or something like that
public bool?[][] SquareStates = new bool?[3][3];
// Maybe a property to show a game is in progress
public bool GameInProgress = false;
// Maybe a function to restart game
public void Restart() { ... }
// And maybe a function to check for a winner
public string CheckWinner() { ... }
// Maybe another function to make AI make its next move
// and updates SquareStates.
public void AINextMove(out int row, out int column) { ... }
}
Once you have a class like that, your form would simply contain an intance of Game and then update the array of SquareStates as buttons are pressed and then checks for winner, calls AINextMove, checks for winner again, then updates its own button states with the new SquareStates.

Related

How do i access specific list object from a function? C#

Im new to programming and this might be some rookie problem that im having, but id appreaciate a hand.
void Sort()
{
List<Lag> lagen = new List<Lag>() { AIK, DIF, MLM, BJK };
List<Lag> sorted = lagen.OrderByDescending(x => x.poäng)
.ThenByDescending(x => x.målSK)
.ThenByDescending(x => x.mål)
.ToList();
Print(sorted);
}
This is my sorting function, where i take one list, and turn it into a list called "sorted".
What i want to do now is let the user pick one of the objects in the sorted list by entering a number. This far iw written the following code. Where int hemlag, and int bortlag are objects in the sorted list.
And now i want to change the value of "Lag hemmalag" & "Lag bortalag" depending on what numbers (what team) the user put in.
So for example, if the user input "int hemlag" is 2.. i want hemmalag = to be the 2nd object in the list "sorted". And now i run into a problem. Cause i cant access that sorted list from this function.
My theories are that it might have to do something with returning that list from the sorting function, but i have not yet found a way to do that...
void ChangeStats(int hemlag, int bortlag, int mål, int insläpp)
{
Sortera();
Lag hemmalag = AIK;
Lag bortalag = AIK;
if (hemlag == 1) { ; }
if (hemlag == 2) { hemmalag = DIF; }
if (hemlag == 3) { hemmalag = MLM; }
if (hemlag == 4) { hemmalag = BJK; }
if (bortlag == 1) { bortalag = AIK; }
if (bortlag == 2) { bortalag = DIF; }
if (bortlag == 3) { bortalag = MLM; }
if (bortlag == 4) { bortalag = BJK; }
hemmalag.mål += mål;
hemmalag.insläppta += insläpp;
bortalag.insläppta += mål;
bortalag.mål += insläpp;
if (mål > insläpp)
{
hemmalag.poäng += 3;
hemmalag.vinster++;
hemmalag.spel++;
bortalag.förlorade++;
bortalag.spel++;
}
if (mål < insläpp)
{
bortalag.poäng += 3;
bortalag.vinster++;
bortalag.spel++;
hemmalag.förlorade++;
hemmalag.spel++;
}
if (mål == insläpp)
{
bortalag.lika++;
bortalag.poäng++;
hemmalag.lika++;
bortalag.poäng++;
}
Console.WriteLine("Stats changed");
Console.WriteLine("---");
Save();
Sortera();
}
Help appreciated, cheers!
A good practice when programming is to try to ensure that a function has a specific purpose, and only does that specific thing. In your case your Sort-function actually does three things, create the list, sort it, and print it. So lets rewrite your sort-function to return the sorted value:
List<Lag> Sort(IEnumerable<Lag> lagen)
{
return lagen.OrderByDescending(x => x.poäng)
.ThenByDescending(x => x.målSK)
.ThenByDescending(x => x.mål)
.ToList();
}
This uses the IEnumerable<Lag> to accept any kind of sequence of Lag, List, array, HashSet etc. It helps make the code more flexible to accept a wider type of arguments.
Assuming you got the printing and user input correct, the change stats function should probably look something like:
List<Lag> ChangeStats(List<Lag> lagen, int hemlagIndex, int bortlagIndex, int mål, int insläpp){
var hemlag = lagen[hemlagIndex];
var bortalag = lagen[bortlagIndex];
// Do the stat-update logic
...
return lagen
}
You should probably also make your safe-method take a sequence of Lag as input, and move sorting and saving outside the ChangeStats method. Again try to make sure each method has a specific purpose.
These examples only uses method parameters for all the data. This is often a good thing since it makes it more obvious what data the method is using. But in some cases it might be preferable to use a field in the class instead, something like:
public class MinaLag{
private List<Lag> lagen = new List<Lag>(){ AIK, DIF, MLM, BJK };
public void Sort(){
lagen = lagen.OrderBy(...);
}
public void ChangeStats(int hemlagIndex, int bortlagIndex, int mål, int insläpp){
var hemlag = lagen[hemlagIndex];
var bortalag = lagen[bortlagIndex];
...
}
public void Print(){...}
public void Save(Stream s){...}
public static MinLag Load(Stream s){...}
}
This wraps a list of the objects and provides methods to do all the required operations on them, removing the need for the user give and receive the list for each called method.
Here is my example on the global scope list. I'm not 100% this can sort the issue but I'm confident.
class Example {
private List<Lag> Lagen {
get;
set;
} // Global Scope - Make it public if you need to access it from another
// class.
public Example() {
this.Lagen = new List<Lag>{AIK, DIF, MLM,
BJK}; // Assign intial values on class execution
}
void Sort() {
// Everything else will be the same but now you can access it from anywhere
// within the class
List<Lag> sorted = Lagen.OrderByDescending(x => x.poäng)
.ThenByDescending(x => x.målSK)
.ThenByDescending(x => x.mål)
.ToList();
Print(sorted);
}
}
your description is very convoluted and I'm not fully getting what you're up to, but...
You can return the sorted list from the Sort() function by changing the return type from void to List and at its bottom just having line like return sorted
You can also consider leaving void as return type but passing original list to it and turning it to a sorted one inside. List is an object so you'll get it back in the calling function and can further work with it there.
private List<Lag> lagen = new List<Lag>() { AIK, DIF, MLM, BJK };
private void Sortera()
{
lagen = lagen.OrderByDescending(x => x.poäng)
.ThenByDescending(x => x.målSK)
.ThenByDescending(x => x.mål)
.ToList();
Print(lagen);
}
private void ChangeStats(int hemlag, int bortlag, int mål, int insläpp)
{
Sortera();
Lag hemmalag = AIK;
Lag bortalag = AIK;
if (hemlag == 1) {; }
if (hemlag == 2) { lagen[1] = AIK }
if (hemlag == 3) { lagen[2] = MLM; }
if (hemlag == 4) { lagen[3] = BJK; }
if (bortlag == 1) { lagen[0] = AIK; }
if (bortlag == 2) { lagen[1] = DIF; }
if (bortlag == 3) { lagen[2] = MLM; }
if (bortlag == 4) { lagen[3] = BJK; }
etc.....
I'm still not sure what the rest of the solution means but this way you can change your list items

WPF: Equals(Control.background, SolidColorBrush) constantly false

I have a List<SolidColorBrush> lColorBrushes and want to compare the Background of some Buttons with it's content. The Buttons are saved in List<Button> lClickedButtons.
foreach (var oBtn in lClickedButtons)
{
for (var i = 0; i < lColorBrushes.Count; i++)
{
if (Equals(oBtn.Background, lColorBrushes[i]))
{
//oBtn gets cool stuff
}
}
}
I did the exact same thing earlier and it worked tottaly fine. But for whatever reason (I dont see any difference to earlier circumstances of my Code) now the if condition is constantly false. Also if for example oBtn.Background and lColorBrushes[i] both are #FFFF0000.
The reason for Equals() returning false, is that these are two entirely different references, that just happen to have the same Color property.
If you want to compare the two SolidColorBrushes, I suggest you use the IEqualityComparer interface, as such: (source).
public class SolidColorBrushComparer : IEqualityComparer<SolidColorBrush>
{
public bool Equals(SolidColorBrush x, SolidColorBrush y)
{
// If you do not care about opacity, disregard it.
return x.Color == y.Color &&
x.Opacity == y.Opacity;
}
public int GetHashCode(SolidColorBrush obj)
{
return new { C = obj.Color, O = obj.Opacity }.GetHashCode();
}
}
Then, you can use it inside your loop as follows:
foreach (var oBtn in lClickedButtons)
{
for (var i = 0; i < lColorBrushes.Count; i++)
{
if (new SoldiColorBrushComparer().Equals(oBtn.Background, lColorBrushes[i]))
{
//oBtn gets cool stuff
}
}
}

C# increment decrement List values

So sorry for this vague question... its doing my head in...
Basically just a test project, use the [+] key to add a bunch of values into the List.... The arrow keys need to go up and down the List values...
When a new value is added to the list the "historySelected" is reset, so that the 'Up Arrow'.. always selects the last item added in the List first, and then if you keep pressing it, it goes back through the List values. At anytime if the 'Down Arrow' key is pressed it needs to go back to the previous value in the List of values. At no point should a Up Arrow key followed by a Down Arrow key show the same List value, and vice versa..
The behavior I'm looking for is much like a developer console with a command history, where Up arrow goes further back in history, and Down arrow the opposite.
Again apologies for the code, its been through so many test changes, currently this works going Up arrow to the start of the List value, and then using the Down arrow to go all the back to the highest List index... but the problem is if you go half way through the List (or inbetween anyway), and switch from Up arrow.. to Down arrow.. the values increment/decrement don't act accordingly... I can't seem to get the right codelogic for it.
Any help or suggestions thanks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ArrowKeys {
class Program {
//public static List<string> cmdHistory = new List<string>() { "1", "2", "3", "4", "5" };
public static List<string> cmdHistory = new List<string>();
public static int cmdHistoryCount = 0;
public static int historySelected = 0;
public static int num = 0;
public static string current = "";
public enum UpDown {
reset,
up,
down
};
public static UpDown LastUpDown;
static void Main(string[] args) {
bool running = true;
while (running) {
ConsoleKeyInfo kb = Console.ReadKey();
switch (kb.Key) {
case ConsoleKey.Escape:
Console.WriteLine("Exit");
running = false;
return;
case ConsoleKey.Add:
cmdHistory.Add(num.ToString());
cmdHistoryCount++;
historySelected= cmdHistoryCount;
LastUpDown = UpDown.reset;
Console.WriteLine(string.Join(" ", cmdHistory.Cast<string>().ToArray()));
num++;
break;
case ConsoleKey.UpArrow:
UpArrow();
LastUpDown = UpDown.up;
Console.WriteLine("UpArrow pressed");
Console.WriteLine(current);
break;
case ConsoleKey.DownArrow:
DownArrow();
LastUpDown = UpDown.down;
Console.WriteLine("DownArrow pressed");
Console.WriteLine(current);
break;
}
}
}
public static int Clamp(int value, int min, int max) {
return (value < min) ? min : (value > max) ? max : value;
}
public static void UpArrow() {
if (cmdHistoryCount != 0) {
if (LastUpDown == UpDown.down) {
if (historySelected - 1 == 0) {
return;
}
}
current = cmdHistory[historySelected - 1];
if (historySelected - 1 == 0) {
return;
}
historySelected--;
}
}
public static void DownArrow() {
if (cmdHistoryCount != 0) {
if (LastUpDown == UpDown.up) {
if (historySelected + 1 > cmdHistoryCount) {
return;
}
}
current = cmdHistory[historySelected - 1];
if (historySelected + 1 > cmdHistoryCount) {
return;
}
historySelected++;
}
}
}
}
It sounds like you simply need to stop your index going out of range. It's not clear what the existing code was intended to do, but your clarification seems to imply it's not necessary. Try this:
public static void UpArrow()
{
historySelected = Math.Max(0, historySelected - 1);
current = cmdHistory[historySelected];
}
public static void DownArrow()
{
var maxIndex = cmdHistory.Count - 1;
historySelected = Math.Min(maxIndex, historySelected + 1);
current = cmdHistory[historySelected];
}
If I'm understanding what you're looking for correctly, a pair of dueling stacks might work for your case. They're going to give you the FILO/LIFO style item access you're looking for. Drop the List and do something like:
var UpStack = new Stack<string>();
var DownStack = new Stack<string>();
On "new item"
UpStack.Push(newItem);
On "Up"
DownStack.Push(UpStack.Pop());
On "Down"
UpStack.Push(DownStack.Pop());
If you wanted a "buffer" item that isn't in either of the stacks, that's easy enough to do by just Popping into the buffer item. It's a little more management, because you'd have to push it onto one stack, then pop the other each time, but it's whatever. There's also the Peek() method, which gets the item on top of a Stack without Popping it, so you use that for your display item, as well.

Most efficient way of evaluating independent variable for a similar outcome

I am doing a project using Unity and C# but I don't feel this is necessarily Unity related. I have two separate hands that are represented by 2 instances of a hand class.
public class HandController
{//....class}
HandController LeftHand = new HandController();
HandController RightHand = new HandController();
I am constantly doing twice the work in a lot of areas to affect the hands because each hand needs to be treated independently. So for instance I am using a Leap motion controller and if one of the hands is not detected I want to inform the user of this. So I change the color of the hand in the update method.
Color notDetected = Color.red;
Color detected = new Color(189/255.0f, 165/255.0f, 134/255.0f);
if (!LeftHandTracked)
LeftHand.renderer.material.color = notDetected;
if (!RightHandTracked)
RightHand.renderer.material.color = notDetected;
if (LeftHandTracked)
LeftHand.renderer.material.color = detected;
if (RightHandTracked)
RightHand.renderer.material.color = detected;
Is there a more efficient way of doing this? I hate having duplicate if conditionals sprawled all over my code. I also am tracking fingers, so each finger needs to be recognized and I get an even worse chain of if conditionals
if (TappedFingers[0] && !_keySpamBlock)
LeftHand.SetSide(true, _pointer);
if (TappedFingers[1] && !_keySpamBlock)
LeftHand.SetSide(true, _middle);
if (TappedFingers[2] && !_keySpamBlock)
LeftHand.SetSide(true, _ring);
if (TappedFingers[3] && !_keySpamBlock)
LeftHand.SetSide(true, _pinky);
if (TappedFingers[4] && !_keySpamBlock)
RightHand.SetSide(true, _pointer);
if (TappedFingers[5] && !_keySpamBlock)
RightHand.SetSide(true, _middle);
if (TappedFingers[6] && !_keySpamBlock)
RightHand.SetSide(true, _ring);
if (TappedFingers[7] && !_keySpamBlock)
RightHand.SetSide(true, _pinky);
_pinky and _ middle and etc.. are hash values I pass into SetSide method in the HandController class that allow me to access the animationcontroller booleans I have set in Unity. SetSide() basically just sends the true if a user taps their finger and it plays an animation on the appropriate finger.
EDIT: To Clarify a little more whats going on
I am connecting to an API by inheriting a class and establishing an event listener:
public class AppListener : ErghisListener {
public delegate void onUpdate(Data d);
public event onUpdate Updated;
public override void OnErghisFrame(Data data)
{
Loom.QueueOnMainThread(() => { this.Updated(data); });
}
}
Then I have a MainController where recieve the data object from the API:
public class MainController: MonoBehaviour{
private AppListener _appListener;
private int _pointer;
private int _middle;
private int _ring;
private int _pinky;
void Start()
{
this._appListener = new AppListener();
this._appListener.Updated += callback;
this._pointer = Animator.StringToHash("Pointer");
this._middle = Animator.StringToHash("Middle");
this._ring = Animator.StringToHash("Ring");
this._pinky = Animator.StringToHash("Pinky");
}
public void callback(Data d)
{
// Here is where all my annoying if conditionals were.
bool[] TappedFingers = d.tappedF;
}
Your first code snippet would look much more logical if it was something like this:
class HandController : MonoBehaviour
{
bool m_Tracked;
Color NotDetected { get { return Color.red; } }
Color Detected { get { return new Color(189/255.0f, 165/255.0f, 134/255.0f); } }
public bool Tracked
{
if (m_Tracked == value) return;
m_Tracked = value;
renderer.material.color = value ? Detected : NotDetected;
}
}
// ...
LeftHand.Tracked = LeftHandTracked;
if (TappedFingers.Length != FINGERS*2)
{
Debug.LogError("Unexpected amount of fingers: " + TappedFingers.Length);
return;
}
for(int i = 0; i < FINGERS; i++)
{
LeftHand.SetSide(TappedFingers[i], i);
}
for(int i = FINGERS; i < FINGERS*2; i++)
{
RightHand.SetSide(TappedFingers[i], i-FINGERS);
}
You could simply use else here.
if (LeftHandTracked)
LeftHand.renderer.material.color = detected;
else
LeftHand.renderer.material.color = notDetected;
I would prefer inline conditional.
LeftHand.renderer.material.color = LeftHandTracked ? detected : notDetected;
As for the second example, you can wrap all the statements in a single if block to remove visual noise:
if (!_keySpamBlock)
{
if (TappedFingers[0])
LeftHand.SetSide(true, _pointer);
if (TappedFingers[1])
LeftHand.SetSide(true, _middle);
}
The other option with Linq (which is not more efficient, but so much prettier):
var sides = new[] { _pointer, _middle };
if (!_keySpamBlock)
TappedFingers.Zip(sides, (x, y) => { if (x) { LeftHand.SetSide(true, y); });
I'd say this is clear and looks good enough. I don't see how polymorphism could help here, but you could investigate it yourself.
for the first part:
LeftHand.renderer.material.color = LeftHandTracked ? detected : notDetected;
RightHand.renderer.material.color = RightHandTracked ? detected : notDetected;
second part:
if(!_keySpamBlock)
{
int index=Array.FindLastIndex(TappedFingers.Take(8).ToArray(), i => i);
switch (index)
{
case 0: {LeftHand.SetSide(true, _pointer); break;}
case 1: {LeftHand.SetSide(true, _middle); break;}
//.........
case 7: {RightHand.SetSide(true, _pinky); break;}
}
}

Optimizing "this" type of loop

I'm currently (and have in the past been) using this loop to look through an array of custom classes and make sure that a boolean member value of each class in the array is equal. Is there a better (more efficient, simpler to code perhaps) way to do this?
Since that explanation is pretty bad and for lack of a better way to explain it, I'll simply ask, "Is there a better way to optimize 'this' loop?"
//set to true so the loop runs
boolean AllArentEqual = true;
while (AllArentEqual){
//do some stuff to make stuff equal
///// Check if stuff is equal /////
//set to false to determine later
AllArentEqual = false;
//check if any aren't equal
for (int i = 1; i < anArrayOfClass.length; i++){
if (anArrayOfClass[i - 1].BooleanValue != anArrayOfClass[i].BooleanValue){
//one isn't equal so set the loop to be re-run
AllArentEqual = true;
}
}
} //loop until stuff is equal
An obvious minor improvement is the addition of a break:
for (int i = 1; i < anArrayOfClass.length; i++){
if (anArrayOfClass[i - 1].BooleanValue != anArrayOfClass[i].BooleanValue){
//one isn't equal so set the loop to be re-run
AllArentEqual = true;
break; // We're done in this round
}
}
Once it is established that not all are equal, there's no point in checking further.
I would rework this a bit by extracting a method, and then potentially doing something like:
AttemptMakeEqual(anArrayOfClass);
while (anArrayOfClass.Any(c => c.BooleanValue != anArrayOfClass[0].BooleanValue))
{
AttemptMakeEqual(anArrayOfClass);
}
// Extract out a method to:
void AttemptMakeEqual(YourClass[] values)
{
//do some stuff to make stuff equal
}
If there is a chance you may have "all equal" values, and you don't always need to run the operation first (ie: your new version), you could just do:
while (anArrayOfClass.Any(c => c.BooleanValue != anArrayOfClass[0].BooleanValue))
{
//do some stuff to make stuff equal
}
I'd maybe do something like this:
class Widget
{
public Widget( bool truthiness )
{
this.Truthiness = truthiness ;
}
public bool Truthiness { get ; private set ; }
}
class FooBar
{
private Widget[] Widgets { get ; private set; }
private Widget[] GetSomeWidgets()
{
throw new NotImplementedException() ;
}
public FooBar()
{
Widgets = GetSomeWidgets() ;
}
private void WorkOnWidgets()
{
throw new NotImplementedException() ;
}
public void MakeEqual()
{
bool areEqual ; // zero or one widget and it's not a problem
while ( !(areEqual=CheckIfAllWidgetsEqual()) )
{
WorkOnWidgets() ;
}
return ;
}
public bool CheckIfAllWidgetsEqual()
{
bool value = true ;
if ( Widgets.Length > 1 )
{
Widget first = Widgets[0] ;
Widget firstUnequal = Widgets.Skip(1).FirstOrDefault( x => x.Truthiness != first.Truthiness ) ;
value = firstUnequal != null ;
}
return value ;
}
}

Categories