I've coded a 2-Player TicTacToe game using command line. Code works when player 1 wins in 3 moves, however after player 1 makes their 3rd mark, the game ends saying that "Player 1 wins" even if they haven't won. I'm new to coding so I know its not the prettiest or shortest way to do this.
NSInteger chosen = 0;
NSInteger player = 1;
NSInteger winner = 0;
NSInteger row = 0;
NSInteger column = 0;
NSInteger arr[4][4] = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};
int main(int argc, const char * argv[])
{
//display new board
NSLog(#"%ld %ld %ld ",arr[1][1], arr[1][2],arr[1][3]);
NSLog(#"%ld %ld %ld ",arr[2][1], arr[2][2],arr[2][3]);
NSLog(#"%ld %ld %ld ",arr[3][1], arr[3][2],arr[3][3]);
do
{
if (player == 1)
{
//player 1's input
NSLog(#"Player 1, please choose a cell.");
NSLog(#"Enter row number(1, 2, or 3).");
scanf("%ld", &row);
NSLog(#"Enter column number(1, 2, or 3).");
scanf("%ld", &column);
//add input to board
arr [row][column] = 1;
//display updated board
NSLog(#"%ld %ld %ld ",arr[1][1], arr[1][2],arr[1][3]);
NSLog(#"%ld %ld %ld ",arr[2][1], arr[2][2],arr[2][3]);
NSLog(#"%ld %ld %ld ",arr[3][1], arr[3][2],arr[3][3]);
chosen++;
//check for winner
if ((arr[1][1] && arr[2][1] && arr[3][1]) == 1) {
winner = 1;
} else if ((arr[1][2] && arr[2][2] && arr[3][2]) == 1) {
winner = 1;
} else if ((arr[1][3] && arr[2][3] && arr[3][3]) == 1) {
winner = 1;
} else if ((arr[1][1] && arr[1][2] && arr[1][3]) == 1) {
winner = 1;
} else if ((arr[2][1] && arr[2][2] && arr[2][3]) == 1) {
winner = 1;
} else if ((arr[3][1] && arr[3][2] && arr[3][3]) == 1) {
winner = 1;
} else if ((arr[3][1] && arr[2][2] && arr[1][3]) == 1) {
winner = 1;
} else if ((arr[1][1] && arr[2][2] && arr[3][3]) == 1) {
winner = 1;
} else player++;
}
if (player == 2)
{
//player 2's input
NSLog(#"Player 2, please choose a cell.");
NSLog(#"Enter row number(1, 2, or 3).");
scanf("%ld", &row);
NSLog(#"Enter column number(1, 2, or 3).");
scanf("%ld", &column);
//add input to board
arr [row][column] = 2;
//display updated board
NSLog(#"%ld %ld %ld ",arr[1][1], arr[1][2],arr[1][3]);
NSLog(#"%ld %ld %ld ",arr[2][1], arr[2][2],arr[2][3]);
NSLog(#"%ld %ld %ld ",arr[3][1], arr[3][2],arr[3][3]);
//add a
chosen++;
if ((arr[1][1] && arr[2][1] && arr[3][1]) == 2) {
winner = 2;
} else if ((arr[1][2] && arr[2][2] && arr[3][2]) == 2) {
winner = 2;
} else if ((arr[1][3] && arr[2][3] && arr[3][3]) == 2) {
winner = 2;
} else if ((arr[1][1] && arr[1][2] && arr[1][3]) == 2) {
winner = 2;
} else if ((arr[2][1] && arr[2][2] && arr[2][3]) == 2) {
winner = 2;
} else if ((arr[3][1] && arr[3][2] && arr[3][3]) == 2) {
winner = 2;
} else if ((arr[3][1] && arr[2][2] && arr[1][3]) == 2) {
winner = 2;
} else if ((arr[1][1] && arr[2][2] && arr[3][3]) == 2) {
winner = 2;
} else player--;
}
//player 1 wins
if (winner == 1) {
NSLog(#"Player 1 won");
return 0;
}
//player 2 wins
if (winner == 2) {
NSLog(#"Player 2 won");
return 0;
}
} while (chosen < 9);
//no winner
NSLog(#"Draw");
return 0;
}
All your comparisons are wrong. Instead of
if ((arr[1][1] && arr[2][2] && arr[3][3]) == 1)
Do
if (arr[1][1]==1 && arr[2][2]==1 && arr[3][3] == 1) {
For player 1. For player 2, use ==2 instead of ==1.
Because arr[1][1] by itself will be true if the value is not zero...
As it is, since true is usually represented as 1, your condition will say player 1 wins whenever there are three tokens in a row (regardless of what they are).
Related
I have to decode file encoded in ASCII. However when I want to decode the file, i get a "?" instead of "é" that testify that the decoding didn't happen properly.
This is the code that I am using. Which condition should I had to properly encode ASCII ?
- (void)_sniffEncoding {
NSStringEncoding encoding = NSUTF8StringEncoding;
uint8_t bytes[CHUNK_SIZE];
NSInteger readLength = [_stream read:bytes maxLength:CHUNK_SIZE];
if (readLength > 0 && readLength <= CHUNK_SIZE) {
[_stringBuffer appendBytes:bytes length:readLength];
[self setTotalBytesRead:[self totalBytesRead] + readLength];
NSInteger bomLength = 0;
if (readLength > 3 && bytes[0] == 0x00 && bytes[1] == 0x00 && bytes[2] == 0xFE && bytes[3] == 0xFF) {
encoding = NSUTF32BigEndianStringEncoding;
bomLength = 4;
} else if (readLength > 3 && bytes[0] == 0xFF && bytes[1] == 0xFE && bytes[2] == 0x00 && bytes[3] == 0x00) {
encoding = NSUTF32LittleEndianStringEncoding;
bomLength = 4;
} else if (readLength > 3 && bytes[0] == 0x1B && bytes[1] == 0x24 && bytes[2] == 0x29 && bytes[3] == 0x43) {
encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISO_2022_KR);
bomLength = 4;
} else if (readLength > 1 && bytes[0] == 0xFE && bytes[1] == 0xFF) {
encoding = NSUTF16BigEndianStringEncoding;
bomLength = 2;
} else if (readLength > 1 && bytes[0] == 0xFF && bytes[1] == 0xFE) {
encoding = NSUTF16LittleEndianStringEncoding;
bomLength = 2;
} else if (readLength > 2 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
encoding = NSUTF8StringEncoding;
bomLength = 3;
} else {
NSString *bufferAsUTF8 = nil;
for (NSInteger triedLength = 0; triedLength < 4; ++triedLength) {
bufferAsUTF8 = [[NSString alloc] initWithBytes:bytes length:readLength-triedLength encoding:NSUTF8StringEncoding];
if (bufferAsUTF8 != nil) {
break;
}
}
if (bufferAsUTF8 != nil) {
encoding = NSUTF8StringEncoding;
} else {
NSLog(#"unable to determine stream encoding; assuming MacOSRoman");
encoding = NSMacOSRomanStringEncoding;
}
}
if (bomLength > 0) {
[_stringBuffer replaceBytesInRange:NSMakeRange(0, bomLength) withBytes:NULL length:0];
}
}
_streamEncoding = encoding;
}
I am looking for an algorithm to determine if there are at least three consecutive numbers in an array. I have found several and tweaked them a bit, but it does not seem to be working. Below is what I am currently doing. The array is sorted using an NSSortDescriptor prior to the loop.
For example:
in an array [5,6,101,102,103] the three consecutive numbers are [101,102,103]
and the below function should return YES.
int c = [checkArray count];
int a,b = 0;
int cnt = 1;
for (int i = 1; i < c; i++)
{
a = [[checkArray objectAtIndex:i] intValue];
b = [[checkArray objectAtIndex:i-1] intValue] - 1;
if (a == b)
{
cnt++;
if (cnt == 3)
return YES;
} else {
cnt = 1;
}
}
return NO;
This is an alternative approach. I haven't tested it, but you should get the idea.
int c = [checkArray count];
int a,b,c = 0;
a = [[checkArray objectAtIndex:0] intValue];
b = [[checkArray objectAtIndex:1] intValue];
for (int i = 2; i < c; i++)
{
c = [[checkArray objectAtIndex:i] intValue];
if (a+2 == b+1 && b+1 == c)
return YES;
a = b;
b = c;
}
return NO;
It has the additional advantage of being easily optimized.
You should be able to do something like...
for (int i = 1; i < checkArray.count-1; i++)
{
int lower = [checkArray[i-1] intValue] +1;
int mid = [checkArray[i] intValue];
int upper = [checkArray[i+1] intValue] -1;
if (lower == mid && mid == upper) {
return YES;
}
}
return NO;
You only need to check each number once. No need to count anything. Each number you check is the middle of three numbers. If the one before and the one after are one less and one greater respectively then the three numbers are consecutive.
I have an array that would has 0-49. When I compare acc_x[i] > acc_x[i-1], it would work for some value until it is comparing 5 and 4, then it say that 4 is bigger than 5 and go into the else statement. Please help.
int main(int argc, const char * argv[])
{
#autoreleasepool {
// insert code here...
//NSLog(#"Hello, World!");
//use velocity not acceleration. sorry for the naming. so run the velocity function for the array first that I wrote a already
NSMutableArray * acc_x = [NSMutableArray array];
NSNumber * temp = 0;
//the highest point or lowest point
NSNumber *highest =0;
NSNumber *lowest = 0;
int flag = 0;
//array for the highest and lowest point
NSMutableArray * array_lowest = [NSMutableArray array];
NSMutableArray * array_highest = [NSMutableArray array];
//array for the time when the highest and the lowest point
NSMutableArray * time_lowest = [NSMutableArray array];
NSMutableArray * time_highest = [NSMutableArray array];
double temp1 = 0;
NSNumber *temp2 = 0;
// the time variable is is just for temp variable. the real variable will be how long it take to have one measurement. i think it was like .001 or something like that but i don't remember. the time have to be in second if it is not in second the conver it.
double time = 0.1;
//trying to find the highest point or the lowest points in the graph from the acceleration
for (int i=0; i<50; i++)
{
//putting 0-49 into the array for testing
temp = [NSDecimalNumber numberWithDouble:i];
[acc_x addObject:temp];
if(i == 2) {
if (acc_x[i] > acc_x[i-1]) {
flag = 0;
}
if(acc_x[i] < acc_x[i-1]){
flag = 1;
}
NSLog(#"flag = %d",flag);
}
if(i>1) {
if(acc_x[i] > acc_x[i-1]) {
NSLog(#"x now is bigger then x past");
}
}
if(i >1) {
if(acc_x[i] > acc_x[i-1]) {
NSLog(#"x now is bigger then x pass");
}
NSLog(#"i = %d , i-1 = %d",i, i-1);
if (flag == 0) {
NSLog(#"flag is 0");
if(acc_x[i] > acc_x[i-1]) {
highest = acc_x[i];
}
else {
NSLog(#"flag going to turn into 1");
[array_highest addObject:highest];
flag = 1;
// calculate the time when the highest point is
temp1 = time * i;
temp2 = [NSNumber numberWithDouble:temp1];
[time_highest addObject:temp2];
}
}
if (flag ==1) {
NSLog(#"flag is 1");
}
}
}
// the size of the array
/* long size = [acc_x count];
for (int i =1; i<size-1; i++) {
NSLog(#"i = %d, flag = %d, array = %#, array[i-1] = %#",i,flag,acc_x[i],acc_x[i-1]);
if (flag == 1) {
if (acc_x[i] < acc_x[i-1]) {
lowest = acc_x[i];
}
if (acc_x[i] > acc_x[i-1]) {
flag = 0;
[array_lowest addObject:lowest];
// the temp1 is storing the time when this point got recorded
temp1 = time * i;
temp2 = [NSNumber numberWithDouble:temp1];
[time_lowest addObject:temp2];
}
}
if (flag == 0) {
if (acc_x[i] > acc_x[i-1]) {
highest = acc_x[i];
NSLog(#"x now is bigger than x-1");
//NSLog("highest = %d", highest);
}
if (acc_x[i] < acc_x[i-1]) {
NSLog(#"x now is less than x-1");
flag = 1;
[array_highest addObject:highest];
// the temp1 is storing the time when this point got recorded
temp1 = time * i;
temp2 = [NSNumber numberWithDouble:temp1];
[time_highest addObject:temp2];
}
}
}*/
//finding the period: time for 1 oscillation in second (remember that it is in second VERY IMPORTANT)
}
return 0;
}
You are comparing objects (NSNumber) instead of their numerical value.
do: if ([acc_x[i] intValue] > [acc_x[i-1] intValue])
instead of if (acc_x[i] > acc_x[i-1])
When I profile my code with Instruments, it shows a leak of Malloc 16 bytes from this function (below), but I never used malloc in this function. Is there a place in this function where I should free some resources?
It may look like a lot of code, but there is really only the variables counts and counts2 as possible offenders I think.
+ (int) trimArray: (NSMutableArray*) source above: (short) max andMin: (short) min
{
int counts[6][7];
int counts2[6][7];
for (int i=0;i<=5;i++)
{
for (int ii=0;ii<7;ii++)
{
counts[i][ii] = 0;
counts2[i][ii] = 0;
}
}
int capacity = (int)[source count]/max;
if (capacity <2)
capacity = 2;
NSMutableArray *itemsToRemove = [[NSMutableArray alloc] initWithCapacity:capacity];
int week,dow,count1,count2;
EntryTimeItem *item;
NSEnumerator *e;
e = [source objectEnumerator];
while (item = [e nextObject])
{
week = item.week_number;
dow = item.day_of_the_week;
if (week >=0 && week <6 && dow >=0 && dow <7)
{
counts[week][dow]++;
}
}
e = [source objectEnumerator];
while (item = [e nextObject])
{
week = item.week_number;
dow = item.day_of_the_week;
if (week >= 0 && week < 6 && dow >= 0 && dow < 7)
{
count2 = counts2[week][dow];
count1 = counts[week][dow];
if (count1 > max)
{
if (!count2)
{
item.time = -1;
item.align = NSCenterTextAlignment;
item.label = [NSString stringWithFormat:#"%d entries",count1];
}
else {
// remove this item if it is after the first item which
// was converted to a placeholder for all the items
[itemsToRemove addObject:item];
}
}
counts2[week][dow]++;
}
}
e = [itemsToRemove objectEnumerator];
while (item = [e nextObject])
{
[source removeObject:item];
}
int count_extra_events = 0;
for (int i=0;i<7;i++)
{
int count_events2 = 0;
for (int ii = 0; ii < 6; ii++)
{
int count3 = counts[ii][i];
if (count3 < max && count3 > min)
count_events2 += count3 - min;
}
// store the greatest value found sofar
if (count_events2 > count_extra_events)
{
count_extra_events = count_events2;
}
}
return count_extra_events;
}
The problem appears to stem from the line:
NSMutableArray *itemsToRemove = [[NSMutableArray alloc] initWithCapacity:capacity];
Please check if there is anyway, the resource itemsToRemove can be freed.
I have a maybe simple problem. I am going to generate 3 random numbers ranging from 0 to 2 and I want to determine if there are any duplicates.
Any ideas?
if (num1 == num2) {
}
else if (num1 == num3) {
}
else if (num2 == num3) {
}
else {
//There are no dups.
}
Checks if there is a duplicate.
if (num1 == num2) {
counter++;
}
if (num1 == num3) {
counter++;
}
if (num2 == num3) {
counter++;
}
This finds how many duplicates there are (for an added bonus).
EDIT:
For x amount of numbers you might want to do this (using 10 as my example amount of ints):
int counter = 0;
int i[10] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
for (int g = 0; g < 10; g++)
{
for (int j = g+1; j < 10; j++)
{
if(i[g] == i[j])
{
counter++;
printf(#"%d\n", counter);
//If this if statement is true then there is a dup... In this case none are found.
}
}
}
How about this?
NSArray *randomNumbers = [[NSArray alloc] initWithObjects:#"0",#"1",#"1",#"2",nil];
NSMutableDictionary *occurenceDict = [[NSMutableDictionary alloc] init];
for (NSString *number in randomNumbers)
{
if ([occurenceDict objectForKey:number] == nil) {
[occurenceDict setValue:[NSNumber numberWithInt:[number intValue]] forKey:number];
int occOfNum = 0;
for (int i = 0; i < [randomNumbers count]; i++) {
NSString *currentNumber = [randomNumbers objectAtIndex:i];
if ([currentNumber compare:number] == NSOrderedSame) {
occOfNum++;
}
}
[occurenceDict setValue:[NSNumber numberWithInt:occOfNum] forKey:number];
}
}
for (NSString *key in occurenceDict) {
NSString *occurrences = [occurenceDict objectForKey:key];
NSLog(#"Number %d is contained %d times", [key intValue], [occurrences intValue]);
}
[randomNumbers release];
[occurenceDict release];
Output:
Number 0 is contained 1 times
Number 1 is contained 2 times
Number 2 is contained 1 times
Edit: Incase you want to know how this works, here is the same version but with comments to help you understand it:
// Create array with the numbers that we have randomly generated
NSArray *randomNumbers = [[NSArray alloc] initWithObjects:#"0",#"1",#"1",#"2",nil];
NSMutableDictionary *occurenceDict = [[NSMutableDictionary alloc] init];
for (NSString *number in randomNumbers)
{
// If this number has not been added to the dictionary
if ([occurenceDict objectForKey:number] == nil) {
// Add it
[occurenceDict setValue:[NSNumber numberWithInt:[number intValue]] forKey:number];
// Find how many times the number occurs with the "randomNumbers" array
int occOfNum = 0;
for (int i = 0; i < [randomNumbers count]; i++) {
NSString *currentNumber = [randomNumbers objectAtIndex:i];
if ([currentNumber compare:number] == NSOrderedSame) {
// We found this number at this index, so increment the found count
occOfNum++;
}
}
// Save the number of times which "number" occurs in the dictionary for later
[occurenceDict setValue:[NSNumber numberWithInt:occOfNum] forKey:number];
}
}
// Iterate through all items in the dictionary and print out the result
for (NSString *key in occurenceDict) {
NSString *occurrences = [occurenceDict objectForKey:key];
NSLog(#"Number %d is contained %d", [key intValue], [occurrences intValue]);
}
// Release alloc'ed memory
[randomNumbers release];
[occurenceDict release];
Crikey, these answers are long-winded! Put your random generated numbers into an NSIndexSet. Test the set before inserting a number and you'll know that the number is already present, and so is a dupe.