Function does not return negative value - c#

I am doing a small project on 4x4 tic-tac-toe game. I am using Alpha Beta Search for finding the next best move. In the alpha beta search, I am using a cutoff evaluation function that is being called in "utility" function of the following algorithm
I implemented everything successfully, but the problem is the utility function doesn't return a negative value and I really don't know why! Following is the function
private static int utility(GameTreeNode gtn, bool isMin = false)
{
int nodeValue = 0;
switch (gtn.NodeBoard.getBoardStatus())
{
case Status.Success:
nodeValue = 50;
if (isMin) nodeValue = -50; /// here
break;
case Status.Incomplete:
if (isMin)
nodeValue = gtn.evaluate(State.X);
else
nodeValue = gtn.evaluate(State.O);
break;
}
// case Status.Draw:
return nodeValue;
}
isMin is set to true, when it is called from MinValue function
isMin is the move of O and the AI's move is X. If O wins the utility is supposed to return -50. But it returns only 0. I debugged the program and it actually assigns -50 to nodeValue (nodeValue changes in the debugger to -50), but when I receive in the Min or Max function, it is zero.
Note: All the int used in the entire project is signed int. No unsigned keyword is used, if you are thinking the function-caller is unsigned
The full code of alpha-beta search is here: http://pastie.org/8538015
Please friends, help as soon as possible.

Since you're using an optional parameter in your method signature, I'd caution you to pay attention to what your code is actually running when entering your function. You said you debugged it and the value gets assigned, but I don't have enough context to know if it only happens in one of many cases or not. Anyway, just be careful with those!
I would rewrite your function like this:
private static int utility(GameTreeNode gtn, bool isMin)
{
switch (gtn.NodeBoard.getBoardStatus())
{
case Status.Success:
return isMin
? -50
: 50;
case Status.Incomplete:
return isMin
? gtn.evaluate(State.X)
: gtn.evaluate(State.O);
default:
throw new NotImplementedException("The status is not implemented.");
}
}
A few improvements I see with this approach:
You don't need to store a value and return it at the end. In your case, you're always storing 50 into nodeValue when you take the Status.Success path, and then sometimes assigning -50 to it. Unless you're adamant about one return in your function, I think this approach is more clear. Might just be my opinion though.
There's a default in the switch statement so that you'll explicitly throw an exception in the case where you have a status that isn't implemented.
There is no optional parameter to your function. I don't see the benefit of making this parameter optional. In my opinion, it only looks like it's adding room to make things harder to debug.
EDIT:
Based on the code at:http://pastie.org/8538015#33,43
It looks like the only time you can ever get utility to return a negative value is when if (gtn.Nodes.Count == 0) return utility(gtn, true); is hit in the private static int MinValue(GameTreeNode gtn, int alpha, int beta) function. Otherwise, unless there's more code which you haven't posted, no other call to the utility function will hit the logical path your going for. You've mentioned when you step into there, you can see the value for nodeValue get properly assigned.
I'm suggesting you change:
// if Terminal-test(state) then return utitly(state)
if (gtn.Nodes.Count == 0) return utility(gtn, true);
gtn.Value = Globals.MAXINT;
To
// if Terminal-test(state) then return utitly(state)
if (gtn.Nodes.Count == 0)
{
int retVal = utility(gtn, true);
return retVal;
}
gtn.Value = Globals.MAXINT;
At least temporarily, and then put a breakpoint on return retVal. If your utility function is actually setting the value you expect like you say, there's no way that it could magically go away when it returns it to the MinValue function. I have a feeling something fishy is happening and the code isn't actually executing the path you expect.

Related

C# - setting a default value for an out parameter of a delegate action

protected IteratorAdvance<int> Advance;
public delegate void IteratorAdvance<T2>(out T2 itemIndex);
public IteratorBase()
{
Advance = delegate(out int i) { i++; }; // <--- here
}
Above is a snippet of a class that is a wrapper for a number of types of loop. In the constructor overload below, the instantiator can specify the method by which the condition of continuing a for loop is determined and also how the control value of that loop is modified on each iteration.
Obviously, the simplest and most likely use of this is to start at 0 and increment by 1 until the last index of the data source is reached. To that end I've provided default methods and an initial value that are effectively (and in this case a very convoluted version of)
for(var i = 0; i < list.Count; i++)
Here's the constructor:
public IteratorBase(IterationStyle style, Func<int, T1, bool> complete, IteratorAdvance<int> advance, bool onErrorAbort = true, int initialValue = 0)
{
Style = style;
InitialValue = initialValue;
Complete = complete;
Advance = advance;
AbortOnError = onErrorAbort;
}
The problem is where I'm incrementing the control value, the compiler wants a default value for a variable (i) that is declared in that scope and because it is an out parameter, cannot accept a default value.
Even if I move the body of the function to a separate method, the same problem exists. I cannot initialise the out parameter prior to the for loop itself initialising it.
case IterationStyle.For:
for (controlValue = InitialValue; !Complete(controlValue, item); Advance(out controlValue))
{
action.TargetItem = item = dataSource[controlValue];
if (!ActWrapper(action))
return false;
}
break;
The only solution I can think of is to intialise the out parameter only on the first call of the method, which will involve using some kind of boolean external to the method. I don't think I'm alone in preferring to avoid that sort of thing. And it turns out it that doesn't work either so I would have to make the control value global. Over my dead body.
Usually, in this sort of situation it means your approach is wrong. But I can't think of another way. I'm hoping you can. Or else tell me how I can either initialise an out parameter or give it a default value.
Just in case anyone else is having a bad brain day, here's the solution. Use ref not out.
Advance = delegate(ref int i) { i++; };

Understanding Return Values in C#

So this question follows on from a previous post that I am just trying to understand in full before I move on to more complicated C# stuff.
My question relates specifically to the return value of a function.
Consider the following function code:
public static void DisplayResult(int PlayerTotal, int DealerTotal){
if (PlayerTotal > DealerTotal) {
Console.WriteLine ("You Win!");
Console.ReadLine ();
}
else if (DealerTotal > PlayerTotal) {
Console.WriteLine ("Dealer Wins!");
Console.ReadLine ();
} else {
Console.WriteLine ("It is a Draw!");
Console.ReadLine ();
}
I could be wrong of course but I believe that the "void" keyword in the first line of code means that the function code result does NOT return a value.
What I am trying to understand is - the function calculates a result. It distributes text (eg: "you win!" etc) based on the result. Is the result of the function not considered a value?
By my own (novice) logic, I would have thought one of two things:
The return value of this function is a string because it is the output of the calculated result.
The return value of this function is an int because it calculates int results.
I hope this makes sense. I think understanding this concept will make it easier for me in future to write functions without second guessing return values. If anyone has an example of a function that actually DOES return a value it would also be appreciated.
A bit of terminology first: C# doesn't have functions, it has methods.
Return values give some value to the method's caller. They aren't related to the statements executed within that method, except for the return statement. The method's signature dictates what (if any) type is returned by that method.
public void NoReturnValue()
{
// It doesn't matter what happens in here; the caller won't get a return value!
}
public int IntReturnValue()
{
// Tons of code here, or none; it doesn't matter
return 0;
}
...
NoReturnValue(); // Can't use the return value because there is none!
int i = IntReturnValue(); // The method says it returns int, so the compiler likes this
A void method, as you have surmised, is one that returns no value. If you wrote:
var myResult = DisplayResult(3, 7)
you would get an error because there is no returned value to assign to myResult.
Your method outputs text to the console. This is a "side effect" of the method, but has nothing to do with its return value.
Also, the fact that your method interacts with ints has nothing to do with what its return value is either.
As a final point. The most basic thing to keep in mind is that a return value is a value that comes after the return keyword:
return "All done!";
Anything that doesn't involve the return keyword is not a return value.
calling Console.writeline is not returning from the DisplayResult method/function
what you have is 3 execution paths only one of which can happen. after it happens the method/function returns void not a string
Tip:
you could get rid of the Console.WriteLine and .ReadLine and replace it with return "result of if statment"; then call your method/function like Console.WriteLine(DisplayResult(/*params*/)); which means you only write Console.WriteLine()/.ReadLine() once
public static string DisplayResult(int PlayerTotal, int DealerTotal){
if (PlayerTotal > DealerTotal) {
return "You Win!"
}
else if (DealerTotal > PlayerTotal) {
return "Dealer Wins!";
} else {
return "It is a Draw!" }}
in main():
Console.WriteLine(DisplayResult(playerscore,dealerscore));
Console.ReadLine();

Stack Overflow in random number generator

For some reason, this code works fine when I don't use a seed in the Random class, but if I try to use DateTime.Now to get a more random number, I get a StackOverflowException! My class is really simple. Could someone tell me what I'm doing wrong here? See MakeUniqueFileName.
public class TempUtil
{
private int strcmp(string s1, string s2)
{
try
{
for (int i = 0; i < s1.Length; i++)
if (s1[i] != s2[i]) return 0;
return 1;
}
catch (IndexOutOfRangeException)
{
return 0;
}
}
private int Uniqueness(object randomObj)
{
switch (randomObj.ToString())
{
case "System.Object":
case "System.String":
return randomObj.ToString()[0];
case "System.Int32":
return int.Parse(randomObj.ToString());
case "System.Boolean":
return strcmp(randomObj.ToString(), "True");
default:
return Uniqueness(randomObj.ToString());
}
}
public string MakeUniqueFileName()
{
return "C:\\windows\\temp\\" + new Random(Uniqueness(DateTime.Now)).NextDouble() + ".tmp";
}
}
You're calling DateTime.Now.ToString(), which doesn't give you one of the strings you're checking for... so you're recursing, calling it with the same string... which still isn't one of the strings you're looking for.
You don't need to use Random to demonstrate the problem. This will do it very easily:
Uniqueness(""); // Tick, tick, tick... stack overflow
What did you expect it to be doing? It's entirely unclear what your code is meant to be doing, but I suggest you ditch the Uniqueness method completely. In fact, I suggest you get rid of the whole class, and use Path.GetTempFileName instead.
In short:
It should say
switch (randomObj.GetType().ToString())
instead of
switch (randomObj.ToString())
But even then this isn't very clever.
You are passing a DateTime instance to your Uniqueness method.
This falls through and calls itself with ToString - on a DateTime instance this will be a formatted DateTime string (such as "21/01/2011 13:13:01").
Since this string doesn't match any of your switch cases (again), the method calls itself again, but the result of calling ToString on a string is the same string.
You have caused an infinite call stack that results in the StackOverflowException.
There is no need to call Uniquness - when creating a Random instance, it will be based on the current time anyways.
I suggest reading Random numbers from the C# in depth website.
The parameter-less constructor of Random already uses the current time as seed value. It uses the time ticks, used internally to represent a DateTime.
A problem with this approach, however, is that the time clock ticks very slowly compared to the CPU clock frequency. If you create a new instance of Random each time you need a random value, it may be, that the clock did not tick between two calls, thus generating the same random number twice.
You can simply solve this problem by creating a single instance of Random.
public class TempUtil {
private static readonly Random random = new Random();
public string MakeUniqueFileName()
{
return #"C:\windows\temp\" + random.NextDouble() + ".tmp";
}
}
This will generate very good random numbers.
By the way
System.IO.Path.GetTempFileName()
automatically creates an empty temporary file with a unique name and returns the full path of that file.
Where to begin.
1. There is already a string compare. Use it. It has been debugged.
2. Your Unique function is illogical. The first two case items return a 'S' perhaps cast to an int. You have neglected the break on the first case.
Your third case is like this:
if (x =="System.Int32") return int.Parse("System.Int32");
That may return 32, or a parse error.
Your fourth case is like this:
if (x == "System.Boolean") return strcmp("System.Boolean", "True");
Your default case is called recursevly (sp) causing the stack overflow (see comment above)
In order fix this program, I recommend you read at least one good book on C#, then rethink your program, then write it. Perhaps Javascript would be a better fit.

Is there a better way to handle a cast exception?

Consider the following function:
public enum Operator
{
EQUAL = 1,
GREATER_THAN = 2
}
public class checkString
{
public static bool isValid(string inputString, string checkString, Operator operation)
{
switch (operation)
{
case Operator.EQUAL:
if (inputString == checkString)
return true;
break;
case Operator.GREATER_THAN:
// Numeric check for greater than
try
{
double inputDouble, checkDouble;
inputDouble = Convert.ToDouble(inputString);
checkDouble = Convert.ToDouble(checkString);
if (inputDouble > checkDouble)
return true;
}
catch (Exception)
{ }
// Date check for greater than
try
{
DateTime inputDate, checkDate;
inputDate = DateTime.Parse(inputString);
checkDate = DateTime.Parse(inputString);
if (inputDate. > checkDate)
return true;
}
catch (Exception)
{ }
break;
}
return false;
}
}
Parameters
inputString: What we want to evaluate
checkString: The criteria (value) that the input must evaluate against
Operator: Enum for the operation we want to perform
Other things to know
Each line in a file is evaluated against this method to return if a condition has been met
The process of evaluating the records in the file checks line by line, in one instance that its equal to the condition. It may also check that the same line is also greater than the condition. Once the checks are done, it moves to the next record
There are no additional event listeners hooked up other than whatever defaults are in place, I am not pushing extra data to debug or trace logs
Problem
What people are going to evaluate is unknown to me at any point in this process but I need to be able to check that 'something' (regardless of what) is equal to, greater than or less than something else. Sure I check other things but I've simplified this function greatly.
That said, using EQUAL or NOT_EQUAL runs fast as can be, processing records in a very large file against said criteria pretty quick and efficiently. Once I added the GREATER_THAN logic, its slow... to the point where it takes minutes to process 20 meg files that used to take half a minute tops.
From what I can tell:
Exceptions are thrown all over the place. There is no guarantee that a field is going to be numeric or of date type. So I must attempt to cast to these data types to attempt to evaluate the condition
When exceptions are thrown, the console gets output where I have not instructed it to do so, its sort of automated
Yes I have a lack of experience in this area and am looking to learn more about exception handling and what really happens behind the scenes because when the other 80% of the records are not numeric, thats a lot of exceptions in a 20 meg, 80 thousand record file.
Is there a better way to handle the cast itself to increase efficiency? I've seen double.Parse / TryParse and can direct cast in front but am not sure which benefits the most.
Use double.TryParse and DateTime.TryParse instead of Convert.ToDouble and DateTime.Parse respectively.
Example:
double result;
if (double.TryParse(someString, out result))
{
Console.WriteLine(result);
}
else
{
// not a valid double
}
You can use TryParse() on those data types. Exceptions are messy and expensive. TryParse will return true/false if it worked or not while NOT throwing an exception. So you can just check the results of the call. Much more efficient than exceptions.
Convert.ToDouble() and Double.Parse() will throw exceptions.
try this code. It isn't the best, but it's better than what you have now considering you don't know what the type could be:
public static bool isValid(string inputString, string checkString, Operator operation)
{
double dblTmp1;
double dblTmp2;
if (Double.TryParse(inputString, out dblTmp1) && double.TryParse(checkString, out dblTmp2))
{
return Compare<Double>(dblTmp1, dblTmp1, operation);
}
DateTime dtTmp1;
DateTime dtTmp2;
if (DateTime.TryParse(inputString, out dtTmp1) && DateTime.TryParse(checkString, out dtTmp2))
{
return Compare<DateTime>(dtTmp1, dtTmp2, operation);
}
throw new InvalidOperationException("Unknown type");
}
public static bool Compare<T>(T obj1, T obj2, Operator operation) where T : IComparable
{
switch (operation)
{
case Operator.EQUAL:
{
return obj1.Equals(obj2);
}
case Operator.GREATER_THAN:
{
return obj1.CompareTo(obj2) > 0;
}
default:
{
throw new InvalidOperationException("Unknown operation");
}
}
}
Keep in mind that using exceptions slows down your program, because behind the scenes the runtime is creating an exception stack in order to be able to unwind this in case an exception is thrown. This stack is maintained regardless of whether your program throws or not, and that overhead is what slows you down the most.
The other answers are probably the best solution in this case, but in the general case you can improve your solution by catching the specific exception, which is probably NumberFormatException or ClassCastException. Catching Exception can cause all kinds of annoying, hard to trace problems (since you're not logging the exception).

Multiple variables in switch statement in c

How to write following statement in c using switch statement in c
int i = 10;
int j = 20;
if (i == 10 && j == 20)
{
Mymethod();
}
else if (i == 100 && j == 200)
{
Yourmethod();
}
else if (i == 1000 || j == 2000) // OR
{
Anymethod();
}
EDIT:
I have changed the last case from 'and' to 'or' later. So I appologise from people who answered my question before this edit.
This scenario is for example, I just wanted to know that is it possible or not. I have google this and found it is not possible but I trust gurus on stackoverflow more.
Thanks
You're pressing for answers that will unnaturally force this code into a switch - that's not the right approach in C, C++ or C# for the problem you've described. Live with the if statements, as using a switch in this instance leads to less readable code and the possibility that a slip-up will introduce a bug.
There are languages that will evaluate a switch statement syntax similar to a sequence of if statements, but C, C++, and C# aren't among them.
After Jon Skeet's comment that it can be "interesting to try to make it work", I'm going to go against my initial judgment and play along because it's certainly true that one can learn by trying alternatives to see where they work and where they don't work. Hopefully I won't end up muddling things more than I should...
The targets for a switch statement in the languages under consideration need to be constants - they aren't expressions that are evaluated at runtime. However, you can potentially get a behavior similar to what you're looking for if you can map the conditions that you want to have as switch targets to a hash function that will produce a perfect hash the matches up to the conditions. If that can be done, you can call the hash function and switch on the value it produces.
The C# compiler does something similar to this automatically for you when you want to switch on a string value. In C, I've manually done something similar when I want to switch on a string. I place the target strings in a table along with enumerations that are used to identify the strings, and I switch on the enum:
char* cmdString = "copystuff"; // a string with a command identifier,
// maybe obtained from console input
StrLookupValueStruct CmdStringTable[] = {
{ "liststuff", CMD_LIST },
{ "docalcs", CMD_CALC },
{ "copystuff", CMD_COPY },
{ "delete", CMD_DELETE },
{ NULL, CMD_UNKNOWN },
};
int cmdId = strLookupValue( cmdString, CmdStringTable); // transform the string
// into an enum
switch (cmdId) {
case CMD_LIST:
doList();
break;
case CMD_CALC:
doCalc();
break;
case CMD_COPY:
doCopy();
break;
// etc...
}
Instead of having to use a sequence of if statements:
if (strcmp( cmdString, "liststuff") == 0) {
doList();
}
else if (strcmp( cmdString, "docalcs") == 0) {
doCalc();
}
else if (strcmp( cmdString, "copystuff") == 0) {
doCopy();
}
// etc....
As an aside, for the string to function mapping here I personally find the table lookup/switch statement combination to be a bit more readable, but I imagine there are people who might prefer the more direct approach of the if sequence.
The set of expressions you have in your question don't look particularly simple to transform into a hash - your hash function would almost certainly end up being a sequence of if statements - you would have basically just moved the construct somewhere else. Jon Skeet's original answer was essentially to turn your expressions into a hash, but when the or operation got thrown into the mix of one of the tests, the hash function broke down.
In general you can't. What you are doing already is fine, although you might want to add an else clause at the end to catch unexpected inputs.
In your specific example it seems that j is often twice the value of i. If that is a general rule you could try to take advantage of that by doing something like this instead:
if (i * 2 == j) /* Watch out for overflow here if i could be large! */
{
switch (i)
{
case 10:
// ...
break;
case 100:
// ...
break;
// ...
}
}
(Removed original answer: I'd missed the fact that the condition was an "OR" rather than an "AND". EDIT: Ah, because apparently it wasn't to start with.)
You could still theoretically use something like my original code (combining two 32-bit integers into one 64-bit integer and switching on that), although there would be 2^33 case statements covering the last condition. I doubt that any compiler would actually make it through such code :)
But basically, no: use the if/else structure instead.

Categories

Resources