@@ -52,13 +52,6 @@ - (void)viewDidLoad
{
[super viewDidLoad];

[NSTimer scheduledTimerWithTimeInterval:PARSE_HEARTBEAT target:self selector:@selector(parseHeartbeat:) userInfo:nil repeats:YES];

self.beginTime = [NSDate date];
self.beginPhase = 0;

[self resetTimer];

//set borders
// self.doneButton.layer.cornerRadius = 6;
// self.rotButton.layer.cornerRadius = 6;
@@ -94,6 +87,15 @@ -(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];

if (!self.single)
{
[NSTimer scheduledTimerWithTimeInterval:PARSE_HEARTBEAT target:self selector:@selector(parseHeartbeat:) userInfo:nil repeats:YES];

self.beginTime = [NSDate date];
self.beginPhase = 0;
}

[self resetTimer];

//tint color the buttons
[self.doneButton setImage: [self.doneButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
@@ -163,12 +165,15 @@ -(void)pressPosition:(NSString *)position
__weak typeof(self) weakSelf = self;
[self shotAnimFromY:-SHOTS_SIZE_START / 2 toPosition:position isHit:hit inView:self.bigView inScreen:self.shots withCallback:
^(){
//send a message to the opponent that you shot that position
weakSelf.battleObject[@"LastMove"] = position;
weakSelf.battleObject[@"LastMover"] = [PFUser currentUser].objectId;
int moveNumber = ((NSNumber *)[weakSelf.battleObject valueForKey:@"MoveNumber"]).intValue;
weakSelf.battleObject[@"MoveNumber"] = @(moveNumber + 1);
[weakSelf.battleObject saveInBackground];
if (!weakSelf.single)
{
//send a message to the opponent that you shot that position
weakSelf.battleObject[@"LastMove"] = position;
weakSelf.battleObject[@"LastMover"] = [PFUser currentUser].objectId;
int moveNumber = ((NSNumber *)[weakSelf.battleObject valueForKey:@"MoveNumber"]).intValue;
weakSelf.battleObject[@"MoveNumber"] = @(moveNumber + 1);
[weakSelf.battleObject saveInBackground];
}

// NSLog(@"Entered turn %@ through own action.", [weakSelf.battleObject valueForKey:@"MoveNumber"]);

@@ -177,6 +182,24 @@ -(void)pressPosition:(NSString *)position
else //and wait for their move
weakSelf.ships.phase = kPhaseWait;
[weakSelf reloadBigScreen];

if (weakSelf.single && weakSelf.ships.phase != kPhaseOver)
{
//this is a very stupid AI
//it doesn't even think to try to attack near hits
NSArray *numbers = [[NSArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", nil];
NSArray *letters = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", nil];
NSMutableArray *combinations = [NSMutableArray new];
for (NSString *number in numbers)
for (NSString *letter in letters)
{
NSString *combination = [NSString stringWithFormat:@"%@%@", letter, number];
if (![weakSelf.ships.shots containsObject:combination])
[combinations addObject:combination];
}
NSString *pick = combinations[arc4random_uniform((u_int32_t)combinations.count)];
[weakSelf enemyMove:pick];
}
}];
}
break;
@@ -306,15 +329,15 @@ - (IBAction)randShips
[self.ships.ships removeAllObjects];

//keep trying to randomize the layout until it works
while (![self randomizeShipLayoutInner])
while (![self randomizeShipLayoutOfScreen:self.ships])
[self.ships.ships removeAllObjects];

//everything snaps into position, because I can't easily handle rotation here
[self reloadBigScreen];
}
}

-(BOOL)randomizeShipLayoutInner
-(BOOL)randomizeShipLayoutOfScreen:(ShipScreen *)screen
{
//place the ships at random, one-by-one
for (int i = 0; i < SHIP_TYPES; i++)
@@ -332,7 +355,7 @@ -(BOOL)randomizeShipLayoutInner
BOOL rotation = arc4random_uniform(2) == 0;

//try to place a ship there
if ([self.ships placeShipAtPosition:positionFrom([self.ships rowLabels][y], [self.ships columnLabels][x]) withRotation:rotation andType:i])
if ([screen placeShipAtPosition:positionFrom([screen rowLabels][y], [screen columnLabels][x]) withRotation:rotation andType:i])
break;
}
}
@@ -377,19 +400,34 @@ - (IBAction)done
{
[self stopTimer];

self.ships.phase = kPhaseWaitForOpponent;
[self.ships reloadLabels];
if (self.single)
{
//arrange AI ships
self.shots = [[ShipScreen alloc] initEmpty];
[self.shots.ships removeAllObjects];
while (![self randomizeShipLayoutOfScreen:self.shots])
{
[self.shots.ships removeAllObjects];
}
self.ships.phase = kPhaseShoot;
}
else
self.ships.phase = kPhaseWaitForOpponent;
self.rotButton.hidden = true;
self.randButton.hidden = true;
self.doneButton.hidden = true;
[self.ships reloadLabels];
[self reloadBigScreen];

NSString *firstUser = [self.battleObject valueForKey:@"FirstUser"];
if ([firstUser isEqualToString:[PFUser currentUser].objectId])
self.battleObject[@"FirstFleet"] = [self.ships fleet];
else
self.battleObject[@"SecondFleet"] = [self.ships fleet];
[self.battleObject saveInBackground];
if (!self.single)
{
NSString *firstUser = [self.battleObject valueForKey:@"FirstUser"];
if ([firstUser isEqualToString:[PFUser currentUser].objectId])
self.battleObject[@"FirstFleet"] = [self.ships fleet];
else
self.battleObject[@"SecondFleet"] = [self.ships fleet];
[self.battleObject saveInBackground];
}

//start the match anim
__weak typeof(self) weakSelf = self;
@@ -510,24 +548,7 @@ -(void)parseHeartbeat:(NSTimer *)timer

//they made their move
NSString *shotAt = [object valueForKey:@"LastMove"];

// NSLog(@"Entered turn %@ through opponent action.", [object valueForKey:@"MoveNumber"]);

BOOL hit = [weakSelf.ships attackPosition:shotAt];
[weakSelf shotAnimFromY:weakSelf.view.frame.size.height + SHOTS_SIZE_START / 2 toPosition:shotAt isHit:hit inView:weakSelf.smallView inScreen:weakSelf.ships withCallback:
^(){
if ([weakSelf victoryOrDefeatFromModel])
weakSelf.ships.phase = kPhaseOver;
else
{
weakSelf.ships.phase = kPhaseShoot;

//set up the timer
[weakSelf resetTimer];
}
[weakSelf reloadBigScreen];
[weakSelf reloadSmallScreen];
}];
[weakSelf enemyMove:shotAt];
}
}
break;
@@ -537,6 +558,28 @@ -(void)parseHeartbeat:(NSTimer *)timer
}];
}

-(void)enemyMove:(NSString *)at
{
// NSLog(@"Entered turn %@ through opponent action.", [object valueForKey:@"MoveNumber"]);

__weak typeof(self) weakSelf = self;
BOOL hit = [weakSelf.ships attackPosition:at];
[self shotAnimFromY:self.view.frame.size.height + SHOTS_SIZE_START / 2 toPosition:at isHit:hit inView:self.smallView inScreen:self.ships withCallback:
^(){
if ([weakSelf victoryOrDefeatFromModel])
weakSelf.ships.phase = kPhaseOver;
else
{
weakSelf.ships.phase = kPhaseShoot;

//set up the timer
[weakSelf resetTimer];
}
[weakSelf reloadBigScreen];
[weakSelf reloadSmallScreen];
}];
}


#pragma mark - animations

@@ -784,12 +827,16 @@ -(void)stopTimer

-(void)resetTimer
{
if (self.single)
return;
[self stopTimer];
self.timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_WARNINGLENGTH target:self selector:@selector(timerWarning:) userInfo:nil repeats:NO];
}

-(void)timerWarning:(NSTimer *)timer
{
if (self.single)
return;
[self makeTimerView:timer];
self.timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_TIMEOUTLENGTH target:self selector:@selector(timerForefeit:) userInfo:nil repeats:NO];
self.tickTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(makeTimerView:) userInfo:nil repeats:YES];
@@ -127,12 +127,13 @@ -(void)reloadLabels
{
NSMutableArray *rowLabels = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", nil];
NSMutableArray *columnLabels = [NSMutableArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", nil];

if (self.phase == kPhasePlace)
{
[self shuffle:rowLabels];
[self shuffle:columnLabels];
}

//you know, the randomized label feature doesn't even make sense anymore
// if (self.phase == kPhasePlace)
// {
// [self shuffle:rowLabels];
// [self shuffle:columnLabels];
// }

//add invisible extra stuff
[rowLabels addObjectsFromArray:[NSArray arrayWithObjects:@"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", nil]];