Reset array after playing the game? - iphone

I made a quiz in iOS with xcode, what i have now is a quiz that generates 20 random answers out of an array, it controls the text of the labels when a button is pushed to check if the answer is correct. The answers are also random generated and i made sure that there weren't mulple answers with the same text. My problem is that when a question is asked, i change the text of an object in my array to "removed"; but when i push start again after i've done the quiz, my array has 20 objects with the string "remove"; my question is: How can I reset my array to it's normal objects? Here is my full code, ignore the comments but it's kind of a junk cause i'm new to ios programming:
//
// ViewController.m
// Mundo Grafia
//
// Created by Axel Lambregts on 2/10/12.
// Copyright (c) 2012 AxelNiels. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// variabelen aanmaken
NSInteger intScore;
NSInteger intRandomMonument;
NSInteger intRandomAnswerPosition;
NSInteger intRandomAnswerA;
NSInteger intRandomAnswerB;
NSInteger intRandomAnswerC;
NSInteger intRandomAnswerD;
NSInteger intArrayEuropeLenght;
NSInteger intAmountOfQuestionsAsked;
NSString *scoreSpatie;
NSString *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},
{#"ArcDeTriompheParis.jpg",#"Paris"},
{#"AtomuimBrussels.jpg",#"Brussels"},
{#"MannekePis.jpg",#"Brussels"},
{#"Colosseum.jpg",#"Rome"},
{#"TreviFountainRome.jpg",#"Rome"},
{#"SagradaFamilia.jpg",#"Barcelona"},
{#"SpanishSchoolMadrid.jpg",#"Madrid"},
{#"KremlinMoskou.jpg",#"Moskou"},
{#"MermaidKopenhagen.jpg",#"Copenhagen"},
{#"MonteCarloMonaco.jpg",#"Monaco"},
{#"AcropolisAthens.jpg",#"Athens"},
{#"ParlementBudapest.jpg",#"Budapest"},
{#"BuildingReykjavik.jpg",#"Reykjavik"},
{#"StatueKiev.jpg",#"Kiev"},
{#"PortOfEuropeLissabon.jpg",#"Lisbon"},
{#"ViewSanMarino.jpg",#"San Marino"},
{#"BridgesPrague.jpg",#"Prague"},
{#"MoskeeAnkara.jpg",#"Ankara"},
{#"TowerBridgeLondon.jpg",#"London"},
{#"BigBenLondon.jpg",#"London"},
{#"LondonEyeLondon.jpg",#"London"},
{#"BrandenburgerTor.jpg",#"Berlin"},
{#"ReichstagBerlin.jpg",#"Berlin"},
{nil,nil}
};
/*
NSArray *arrEurope = #[
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"AtomuimBrussels.jpg",#"Brussels"],
#[#"MannekePis.jpg",#"Brussels"],
#[#"Colosseum.jpg",#"Rome"],
#[#"TreviFountainRome.jpg",#"Rome"],
#[#"SagradaFamilia.jpg",#"Barcelona"],
#[#"SpanishSchoolMadrid.jpg",#"Madrid"],
#[#"KremlinMoskou.jpg",#"Moskou"],
#[#"MermaidKopenhagen.jpg",#"Copenhagen"],
#[#"MonteCarloMonaco.jpg",#"Monaco"],
#[#"AcropolisAthens.jpg",#"Athens"],
#[#"ParlementBudapest.jpg",#"Budapest"],
#[#"BuildingReykjavik.jpg",#"Reykjavik"],
#[#"StatueKiev.jpg",#"Kiev"],
#[#"PortOfEuropeLissabon.jpg",#"Lisbon"],
#[#"ViewSanMarino.jpg",#"San Marino"],
#[#"BridgesPrague.jpg",#"Prague"],
#[#"MoskeeAnkara.jpg",#"Ankara"],
#[#"TowerBridgeLondon.jpg",#"London"],
#[#"BigBenLondon.jpg",#"London"],
#[#"LondonEyeLondon.jpg",#"London"],
#[#"BrandenburgerTor.jpg",#"Berlin"],
#[#"ReichstagBerlin.jpg",#"Berlin"]
];
*/
//methode'start' wanneer er op de start-knop wordt gedrukt
-(IBAction)start{
[self NewQuestionEurope];
intAmountOfQuestionsAsked = 0;
//reset and show score
intScore = 0;
score.text = [NSString stringWithFormat:#"%d", intScore];
//make buttons and labels visible
Start.hidden = YES;
question.hidden = NO;
score.hidden = NO;
scoretext.hidden = NO;
imageContainer.hidden = NO;
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
answerA.textColor = [UIColor greenColor];
answerB.textColor = [UIColor greenColor];
answerC.textColor = [UIColor greenColor];
answerD.textColor = [UIColor greenColor];
clickButtonA.hidden = NO;
clickButtonB.hidden = NO;
clickButtonC.hidden = NO;
clickButtonD.hidden = NO;
GoodFalse.hidden = NO;
GoodFalse.text=#"Press a button to answer";
GoodFalse.textColor = [UIColor greenColor];
question.text = #"Where is this picture taken?";
}//einde start
-(IBAction)Reset{
score.text= #"gelukt";
}
-(IBAction)NewQuestionEurope{
if(intAmountOfQuestionsAsked == 19){
question.text = [#"Uw score is: "stringByAppendingString: [NSString stringWithFormat:#"%d", intScore]];
Start.hidden = NO;
question.hidden = NO;
score.hidden = YES;
scoretext.hidden = YES;
imageContainer.hidden = YES;
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
clickButtonA.hidden = YES;
clickButtonB.hidden = YES;
clickButtonC.hidden = YES;
clickButtonD.hidden = YES;
GoodFalse.hidden = YES;
Start.titleLabel.text = #"END";
}
else{
intAmountOfQuestionsAsked ++;
//Deze lus geeft aan intArrayEuropeLenght de waarde van hoeveel rijen de array bevat//
intArrayEuropeLenght = 0;
while (arrEurope[intArrayEuropeLenght][0] != NULL)
{
intArrayEuropeLenght++;
}
//score.text = [NSString stringWithFormat:#"%d", intScore];
scoreSpatie = [
[NSString stringWithFormat:#"%d", intScore]
stringByAppendingString:#"/"];
score.text = [
scoreSpatie
stringByAppendingString:[NSString stringWithFormat:#"%d", intAmountOfQuestionsAsked]
];
// Randoms genereren voor: 4 random antwoorden; 1 random afbeelding; een random positie om het juiste antwoord in te plaatsen
intRandomMonument = arc4random()%intArrayEuropeLenght;
intRandomAnswerA = arc4random()%intArrayEuropeLenght;
intRandomAnswerB = arc4random()%intArrayEuropeLenght;
intRandomAnswerC = arc4random()%intArrayEuropeLenght;
intRandomAnswerD = arc4random()%intArrayEuropeLenght;
intRandomAnswerPosition = arc4random()%4;
while(arrEurope[intRandomMonument][0] == #"removed"){
intRandomMonument = arc4random()%intArrayEuropeLenght;
}
//Random antwoorden maken
answerA.text = #"";
answerB.text = #"";
answerC.text = #"";
answerD.text = #"";
if(answerA.text = #""){
answerA.text = arrEurope[intRandomAnswerA][1];
}
if(answerB.text = #""){
answerB.text = arrEurope[intRandomAnswerB][1];
}
if(answerC.text = #""){
answerC.text = arrEurope[intRandomAnswerC][1];
}
if(answerD.text = #""){
answerD.text = arrEurope[intRandomAnswerD][1];
}
switch(intRandomAnswerPosition)
{
case 0: answerA.text = arrEurope[intRandomMonument][1];
break;
case 1: answerB.text = arrEurope[intRandomMonument][1];
break;
case 2: answerC.text = arrEurope[intRandomMonument][1];
break;
case 3: answerD.text = arrEurope[intRandomMonument][1];
};
//als er antwoorden hetzelfde zijn, voor de gelijke een random blijven maken tot ze niet hetzelfde zijn
if(
[answerA.text isEqualToString: answerB.text]||
[answerA.text isEqualToString: answerC.text]||
[answerA.text isEqualToString: answerD.text]
){
answerA.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerB.text isEqualToString: answerA.text]||
[answerB.text isEqualToString: answerC.text]||
[answerB.text isEqualToString: answerD.text]
){
answerB.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerC.text isEqualToString: answerA.text]||
[answerC.text isEqualToString: answerB.text]||
[answerC.text isEqualToString: answerD.text]
){
answerC.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerD.text isEqualToString: answerA.text]||
[answerD.text isEqualToString: answerB.text]||
[answerD.text isEqualToString: answerC.text]
){
answerD.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
//Laat de afbeelding zien van het gekozen monument (via random gekozen)
imageContainer.image = [UIImage imageNamed: arrEurope[intRandomMonument][0]];
}
}
//hier onder zit ergens een fout want hij geeft precies random juist en fout :)
//kan zijn dat het opgelost is vanaf we niet 2x dezelfde vragen hebben maar ik denk het niet.
//press buttonA
-(IBAction)AnswerA {
if([answerA.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonB
-(IBAction)AnswerB {
if([answerB.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonC (works)
-(IBAction)AnswerC {
if([answerC.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonD
-(IBAction)AnswerD {
if([answerD.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//hier onder niets wijzigen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

I see 2 options:
you call the init line again...
String *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},...
Or you add a third row to your array and put the "removed" (i would call it "used") parameter there. In the last case you can then just iterate over your array again and put the "removed" back to "active"

Either make a copy of arrEurope on game start and restore to it when the game is restarted or use some other array to mark a question as removed. I would personally try to use option 2.

Related

Line Chart - Display xAxis at bottom

I've looked everywhere and tried various approaches and cannot figure this out.
How do I position the xAxis at the bottom of the line chart?
In viewDidLoad:
[self initChartProperties];
[self updateChartData:5];
initChartProperties:
- (void)initChartProperties2 {
_chartView.delegate = self;
_chartView.descriptionText = #"";
_chartView.noDataTextDescription = #"You need to provide data for the chart.";
_chartView.dragEnabled = YES;
_chartView.pinchZoomEnabled = YES;
_chartView.legend.enabled = NO;
[_chartView setScaleEnabled:YES];
_chartView.leftAxis.customAxisMax = 21;
_chartView.leftAxis.customAxisMin = 0;
_chartView.leftAxis.drawZeroLineEnabled = NO;
_chartView.leftAxis.enabled = YES;
_chartView.xAxis.axisLineWidth = 2.0f;
_chartView.xAxis.drawAxisLineEnabled = YES;
_chartView.rightAxis.enabled = NO;
[_chartView.viewPortHandler setMaximumScaleY: 2.f];
[_chartView.viewPortHandler setMaximumScaleX: 2.f];
}
updateChartData:
- (void)updateChartData:(int)count {
NSMutableArray *xVals = [[NSMutableArray alloc] init];
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++) {
[xVals addObject:[#(i) stringValue]];
}
for (int i = 0; i < count; i++) {
[yVals addObject:[[ChartDataEntry alloc] initWithValue:i xIndex:i]];
}
LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithYVals:yVals label:#""];
set1.lineWidth = 1.0;
set1.circleRadius = 0.0;
set1.drawCircleHoleEnabled = NO;
set1.valueFont = [UIFont fontWithName:#"HelveticaNeue-Light" size:9.0f];
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
LineChartData *data = [[LineChartData alloc] initWithXVals:xVals dataSets:dataSets];
_chartView.data = data;
}
Result:
line graph
I just want the xAxis values to be rendered at the bottom of the graph, not the top.
Sorry for the seemingly simple question.
Appreciate any help.
Nevermind - finally figured it out
_chartView.xAxis.labelPosition = XAxisLabelPositionBottom;
In the most recent version (currently 3.0) you can do it with
_chartView.xAxis.labelPosition = XAxis.LabelPosition.bottom

Core plot : bars disappears when switching app to background and then to foreground while drawing a bar graph

My bar graph disappears when I switch my app to background and then again comes back to foreground.
It's like shown below :
||| || ||
So in the above picture I have gaps, that means when my app is in background core plot does not draw bar graph. Is it a limitation of core plot?
My main task is to draw one bar per second and I have done this, but it's not working while in background. Is there some other alternate option by which I can achieve this?
Here is what I tried:
I made my graph object nil and then tried it reloading when app again comes back to foreground. But it didn't work.
-(void)redrawGraphWhenApplicationEntersForeground
{
NSLog(#"reload graph");
NSLog(#"all plots : %# , %#", [self.graph allPlots], plotArray);
DDLogInfo(#"relaod graph when entered in Foreground ");
// [self.data removeAllObjects];
//Create graph and set it as host view's graph
self.graph = nil;
[self.graph reloadDataIfNeeded];
}`
Here is my full code :
// Update is called by a timer ( of 10 second) , so that each second this method will be called and it will draw a bar.
- (void)update:(id)data1 withState:(NSInteger) type
{
switch (type) {
case ZAP_UPDATE:
if(curLinkType == DOWNLINK)
{
[self drawDownlinkGrpah];
}else if(curLinkType == UPLINK)
{
[self drawUplinkGrpah];
}
[gauge setValue:speedValue];
break;
case ZAP_DONE:
[self displayDone:type speedBps:speedBps pktLoss:pktLoss srcdst:[zap destinationAddress]];
onTap = false;
runningTime=0;
if(gauge != nil){
[gauge setValue:0];
}
{
NSArray *parameter = [NSArray arrayWithObjects: speed, unit, nil];
[self performSelector:#selector(stopGauge:) withObject:parameter afterDelay:0.2];
}
}
}
- (void)drawDownlinkGrpah {
DownlinCount++;
self.downlinkdata = [NSMutableArray array];
double position = DownlinCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.downlinkdata addObject:bar];
self.data = self.downlinkdata;
[self generateBarPlotForDownlink:YES];
}
- (void)drawUplinkGrpah {
UplinkCount++;
self.uplinkdata = [NSMutableArray array];
double position = UplinkCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.uplinkdata addObject:bar];
self.data = self.uplinkdata;
[self generateBarPlotForDownlink:NO];
}
- (NSInteger)getBarposition:(NSInteger)samplesize {
return (4*10)/samplesize;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)resetGraph:(UIImageView*) imageview {
for(UIView *view in imageview.subviews)
[view removeFromSuperview];
[imageview setImage:[UIImage imageNamed:#"graph_container"]];
}
#pragma mark -
-(void)appGoesinBackground
{
// NSLog(#"make nil graph");
// DDLogInfo(#"remove graph when entered in background ");
//
self.graph = nil;
// [self.data removeAllObjects];
[plotArray removeAllObjects]; // remove all data before entering to background
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(redrawGraphWhenApplicationEntersForeground)
name: UIApplicationDidBecomeActiveNotification
object: nil];
}
// redraw graph ..
-(void)redrawGraphWhenApplicationEntersForeground
{
NSLog(#"reload graph");
NSLog(#"all plots : %# , %#", [self.graph allPlots], plotArray);
DDLogInfo(#"relaod graph when entered in Foreground ");
// [self.data removeAllObjects];
//Create graph and set it as host view's graph
// self.graph = nil;
//
for (CPTBarPlot *p in plotArray) {
// [self.graph addPlot:p];
[p reloadData];
}
}
#pragma mark - generate bar plot
- (void)generateBarPlotForDownlink:(BOOL)enabled
{
NSLog(#"generateBarPlotForDownlink >>>>>>");
//Create host view
self.hostingView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(-35, -20, 128, 73)];
//Create graph and set it as host view's graph
self.graph = [[CPTXYGraph alloc] initWithFrame:self.downlinkImageView.frame];
self.graph.plotAreaFrame.masksToBorder = NO;
[self.hostingView setHostedGraph:self.graph];
if(enabled) // for downlink graph ..
{
self.downlinkImageView.image=nil;
[self.downlinkImageView addSubview:self.hostingView];
}
else{ // for uplink graph ..
self.uplinkImageView.image=nil;
[self.uplinkImageView addSubview:self.hostingView];
}
// Create bar plot and add it to the graph
CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
plot.dataSource = self;
plot.delegate = self;
//set axes ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat((AXIS_END - AXIS_START)+1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat(maxYRange)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.xAxis.minorTickLength = 1.0f;
axisSet.yAxis.minorTickLength = 1.0f;
axisSet.hidden=YES;
axisSet.xAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
float barwidht = (2*10.0)/(float)durationval;
NSString *inStr = [NSString stringWithFormat: #"%f", barwidht];
plot.barWidth = [[NSDecimalNumber decimalNumberWithString:inStr] // Need to change according sample // 1.5 for 10 , 0.75 for 20
decimalValue];
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:#"5.0"]
decimalValue];
plot.barCornerRadius = 0.0;
// Remove bar outlines
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor clearColor];
plot.lineStyle = borderLineStyle;
plot.identifier = #"chocoplot";
[self.graph addPlot:plot];
// Add plot to array in case if app is moved to background state ..
[plotArray addObject:plot];
NSLog(#"plot : %#",plot);
NSLog(#"plot added ..%lu", (unsigned long)plotArray.count );
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:#"chocoplot"] )
return [self.data count];
return 0;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:#"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
if(fieldEnum == CPTBarPlotFieldBarLocation)
return [bar valueForKey:BAR_POSITION];
else if(fieldEnum ==CPTBarPlotFieldBarTip)
return [bar valueForKey:BAR_HEIGHT];
}
return [NSNumber numberWithFloat:0];
}
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot
recordIndex:(NSUInteger)index
{
if ( [barPlot.identifier isEqual:#"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
CPTGradient *gradient = [CPTGradient gradientWithBeginningColor:[CPTColor redColor]
endingColor:[bar valueForKey:#"COLOR"]
beginningPosition:0.0 endingPosition:0.6 ];
[gradient setGradientType:CPTGradientTypeAxial];
[gradient setAngle:320.0];
CPTFill *fill = [CPTFill fillWithGradient:gradient];
return fill;
}
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:1.0]];
}
Screenshot:
You don't need to create a new graph every time you get new plot data. Just add the new point to the data array and call -reloadData on the plot.
When the app goes into the background, just clear your data array and call -reloadData on the plot. It will reload the empty data and display the graph when the app comes back to the foreground. There's no reason to set self.graph to nil unless you remove the graph from the hosting view and you want it to go away. From what I can see in the posted code, the graph is still in the hosting view, but you've lost your reference to it, making any updates you make when the app comes to the foreground ineffective.
Here is the code that worked for me :
- (void)drawDownlinkGrpah {
NSLog(#"drawDownlinkGrpah CAlled");
DownlinCount++;
double position = DownlinCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.downlinkdata addObject:bar];
self.data = self.downlinkdata;
[self generateBarPlotForDownlink:YES];
}
#pragma mark - generate bar
- (void)generateBarPlotForDownlink:(BOOL)enabled
{
if(enabled)
{
self.downlinkImageView.image=nil;
if(![self.hostingView isDescendantOfView:self.downlinkImageView])
{
// Configure hosting view so that it appears from fresh ..
[self configureGraph];
[self.downlinkImageView addSubview:self.hostingView];
NSLog(#"hosting view added in downlink view ");
}
}
else
{
self.uplinkImageView.image=nil;
// if hosting view is not in uplink view
if(![self.hostingView isDescendantOfView:self.uplinkImageView])
{
// Configure hosting view so that it appears from fresh ..
[self configureGraph];
[self.uplinkImageView addSubview:self.hostingView];
NSLog(#"hosting view added in uplink view ");
}
}
//set axes ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat((AXIS_END - AXIS_START)+1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat(maxYRange)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.xAxis.minorTickLength = 1.0f;
axisSet.yAxis.minorTickLength = 1.0f;
axisSet.hidden=YES;
axisSet.xAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
// Create bar plot and add it to the graph
NSLog(#"plot created %ld", (long)durationval);
CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
plot.dataSource = self;
plot.delegate = self;
float barwidht = (2*10.0)/(float)durationval;
NSString *inStr = [NSString stringWithFormat: #"%f", barwidht]; //CPTDecimalFromDouble(2.0);
plot.barWidth = [[NSDecimalNumber decimalNumberWithString:inStr]
decimalValue];// Need to change according sample // 1.5 for 10 , 0.75 for 20
plot.barWidth = CPTDecimalFromDouble(barwidht);
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:#"5.0"]
decimalValue];
plot.barCornerRadius = 0.0;
// Remove bar outlines
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor clearColor];
plot.lineStyle = borderLineStyle;
plot.identifier = #"chocoplot";
[self.graph addPlot:plot];
}
#pragma mark - core plot data source and delegate methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:#"chocoplot"] )
return [self.data count];
return 0;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:#"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
if(fieldEnum == CPTScatterPlotFieldX)
return [bar valueForKey:BAR_POSITION];
else if(fieldEnum ==CPTScatterPlotFieldY)
return [bar valueForKey:BAR_HEIGHT];
}
return [NSNumber numberWithFloat:0];
}
drawDownlinkGraph method would be called each second using a timer and it will call generateBarPlotForDownlink: Method every second . And bar will be drawn each second on a real time basis even if APP is in background.

NSTimer countdown skips last second (not using last milliseconds)

I have a NS timer countdown which works perfectly fine thanks to your answers. However, my timer skips the last second so that it does not count the last 0s:99 ms . Is there anything wrong with my code? Best regards!
-(void) setTimer {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = 99;
tmp.secondsCount = 2;
tmp.countdownTimerGame = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(timerRun) userInfo:nil repeats:YES];
}
-(void) timerRun {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = tmp.milisecondsCount - 1;
if(tmp.milisecondsCount == 0){
tmp.secondsCount -= 1;
if (tmp.secondsCount == 0){
//Stuff for when the timer reaches 0
[tmp.countdownTimerGame invalidate];
tmp.countdownTimerGame = nil;
tmp.lives = tmp.lives - 1;
NSString *newLivesOutput = [NSString stringWithFormat:#"%d", tmp.lives];
livesLabel.text = newLivesOutput;
if (tmp.lives == 0) {
timeLabel.text = #"0:00";
[self performSelector:#selector(stopped) withObject:nil afterDelay:2.0];
}
else {[self setTimer]; }
}
else
tmp.milisecondsCount = 99;
}
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%2d", tmp.secondsCount, tmp.milisecondsCount];
timeLabel.text = timerOutput;
}
try to change this
-(void) setTimer {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = 100;// Change this from 99 to 100
tmp.secondsCount = 2;
tmp.countdownTimerGame = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(timerRun) userInfo:nil repeats:YES];
}
For a start, get rid of
else {[self setTimer]; }
Otherwise you are restarting the timer every time that selector fires.
Next: swap these two around
tmp.secondsCount -= 1;
if (tmp.secondsCount == 0){
to
else {
tmp.secondsCount -= 1;
tmp.milisecondsCount = 99;
}
like so:
-(void) timerRun {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = tmp.milisecondsCount - 1;
if(tmp.milisecondsCount == 0){
if (tmp.secondsCount == 0){
//Stuff for when the timer reaches 0
[tmp.countdownTimerGame invalidate];
tmp.countdownTimerGame = nil;
tmp.lives = tmp.lives - 1;
NSString *newLivesOutput = [NSString stringWithFormat:#"%d", tmp.lives];
livesLabel.text = newLivesOutput;
if (tmp.lives == 0) {
timeLabel.text = #"0:00";
[self performSelector:#selector(stopped) withObject:nil afterDelay:2.0];
}
}
else
{
tmp.milisecondsCount = 99;
tmp.secondsCount -= 1;
}
}
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%2d", tmp.secondsCount, tmp.milisecondsCount];
timeLabel.text = timerOutput;
}

Saving NSInteger intScore when application is closed

I made an app with xcode 4, all code is in the main code file so i don't have more classes.
I have 3 views but only use one at the moment. Now in the game i save an integer as score, and at the end of the game it shows what your score is, but i wanted to know how i can let that int show up in a label in one of my other 2 views, and how i can keep it there when the application is restarted. I'm sorry of my bad english but i'm new to this objective C and iphone Apps. Thank You!
and how do i put something in an other viewcontroller, can't fine codefile
this is the code:
//
// ViewController.m
// Mundo Grafia
//
// Created by Axel Lambregts on 2/10/12.
// Copyright (c) 2012 AxelNiels. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// variabelen aanmaken
NSInteger intScore;
NSInteger intRandomMonument;
NSInteger intRandomAnswerPosition;
NSInteger intRandomAnswerA;
NSInteger intRandomAnswerB;
NSInteger intRandomAnswerC;
NSInteger intRandomAnswerD;
NSInteger intArrayEuropeLenght;
NSInteger intAmountOfQuestionsAsked;
NSString *scoreSpatie;
NSString *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},
{#"ArcDeTriompheParis.jpg",#"Paris"},
{#"AtomuimBrussels.jpg",#"Brussels"},
{#"MannekePis.jpg",#"Brussels"},
{#"Colosseum.jpg",#"Rome"},
{#"TreviFountainRome.jpg",#"Rome"},
{#"SagradaFamilia.jpg",#"Barcelona"},
{#"SpanishSchoolMadrid.jpg",#"Madrid"},
{#"KremlinMoskou.jpg",#"Moskou"},
{#"MermaidKopenhagen.jpg",#"Copenhagen"},
{#"MonteCarloMonaco.jpg",#"Monaco"},
{#"AcropolisAthens.jpg",#"Athens"},
{#"ParlementBudapest.jpg",#"Budapest"},
{#"BuildingReykjavik.jpg",#"Reykjavik"},
{#"StatueKiev.jpg",#"Kiev"},
{#"PortOfEuropeLissabon.jpg",#"Lisbon"},
{#"ViewSanMarino.jpg",#"San Marino"},
{#"BridgesPrague.jpg",#"Prague"},
{#"MoskeeAnkara.jpg",#"Ankara"},
{#"TowerBridgeLondon.jpg",#"London"},
{#"BigBenLondon.jpg",#"London"},
{#"LondonEyeLondon.jpg",#"London"},
{#"BrandenburgerTor.jpg",#"Berlin"},
{#"ReichstagBerlin.jpg",#"Berlin"},
{nil,nil}
};
/*
NSArray *arrEurope = #[
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"AtomuimBrussels.jpg",#"Brussels"],
#[#"MannekePis.jpg",#"Brussels"],
#[#"Colosseum.jpg",#"Rome"],
#[#"TreviFountainRome.jpg",#"Rome"],
#[#"SagradaFamilia.jpg",#"Barcelona"],
#[#"SpanishSchoolMadrid.jpg",#"Madrid"],
#[#"KremlinMoskou.jpg",#"Moskou"],
#[#"MermaidKopenhagen.jpg",#"Copenhagen"],
#[#"MonteCarloMonaco.jpg",#"Monaco"],
#[#"AcropolisAthens.jpg",#"Athens"],
#[#"ParlementBudapest.jpg",#"Budapest"],
#[#"BuildingReykjavik.jpg",#"Reykjavik"],
#[#"StatueKiev.jpg",#"Kiev"],
#[#"PortOfEuropeLissabon.jpg",#"Lisbon"],
#[#"ViewSanMarino.jpg",#"San Marino"],
#[#"BridgesPrague.jpg",#"Prague"],
#[#"MoskeeAnkara.jpg",#"Ankara"],
#[#"TowerBridgeLondon.jpg",#"London"],
#[#"BigBenLondon.jpg",#"London"],
#[#"LondonEyeLondon.jpg",#"London"],
#[#"BrandenburgerTor.jpg",#"Berlin"],
#[#"ReichstagBerlin.jpg",#"Berlin"]
];
*/
//methode'start' wanneer er op de start-knop wordt gedrukt
-(IBAction)start{
[self NewQuestionEurope];
intAmountOfQuestionsAsked = 0;
//reset and show score
intScore = 0;
score.text = [NSString stringWithFormat:#"%d", intScore];
//make buttons and labels visible
Start.hidden = YES;
question.hidden = NO;
score.hidden = NO;
scoretext.hidden = NO;
imageContainer.hidden = NO;
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
answerA.textColor = [UIColor greenColor];
answerB.textColor = [UIColor greenColor];
answerC.textColor = [UIColor greenColor];
answerD.textColor = [UIColor greenColor];
clickButtonA.hidden = NO;
clickButtonB.hidden = NO;
clickButtonC.hidden = NO;
clickButtonD.hidden = NO;
GoodFalse.hidden = NO;
GoodFalse.text=#"Press a button to answer";
GoodFalse.textColor = [UIColor greenColor];
question.text = #"Where is this picture taken?";
}//einde start
-(IBAction)Reset{
score.text= #"gelukt";
}
-(IBAction)NewQuestionEurope{
if(intAmountOfQuestionsAsked == 19){
question.text = [#"Uw score is: "stringByAppendingString: [NSString stringWithFormat:#"%d", intScore]];
Start.hidden = NO;
question.hidden = NO;
score.hidden = YES;
scoretext.hidden = YES;
imageContainer.hidden = YES;
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
clickButtonA.hidden = YES;
clickButtonB.hidden = YES;
clickButtonC.hidden = YES;
clickButtonD.hidden = YES;
GoodFalse.hidden = YES;
Start.titleLabel.text = #"END";
}
else{
intAmountOfQuestionsAsked ++;
//Deze lus geeft aan intArrayEuropeLenght de waarde van hoeveel rijen de array bevat//
intArrayEuropeLenght = 0;
while (arrEurope[intArrayEuropeLenght][0] != NULL)
{
intArrayEuropeLenght++;
}
//score.text = [NSString stringWithFormat:#"%d", intScore];
scoreSpatie = [
[NSString stringWithFormat:#"%d", intScore]
stringByAppendingString:#"/"];
score.text = [
scoreSpatie
stringByAppendingString:[NSString stringWithFormat:#"%d", intAmountOfQuestionsAsked]
];
// Randoms genereren voor: 4 random antwoorden; 1 random afbeelding; een random positie om het juiste antwoord in te plaatsen
intRandomMonument = arc4random()%intArrayEuropeLenght;
intRandomAnswerA = arc4random()%intArrayEuropeLenght;
intRandomAnswerB = arc4random()%intArrayEuropeLenght;
intRandomAnswerC = arc4random()%intArrayEuropeLenght;
intRandomAnswerD = arc4random()%intArrayEuropeLenght;
intRandomAnswerPosition = arc4random()%4;
while(arrEurope[intRandomMonument][0] == #"removed"){
intRandomMonument = arc4random()%intArrayEuropeLenght;
}
//Random antwoorden maken
answerA.text = #"";
answerB.text = #"";
answerC.text = #"";
answerD.text = #"";
if(answerA.text = #""){
answerA.text = arrEurope[intRandomAnswerA][1];
}
if(answerB.text = #""){
answerB.text = arrEurope[intRandomAnswerB][1];
}
if(answerC.text = #""){
answerC.text = arrEurope[intRandomAnswerC][1];
}
if(answerD.text = #""){
answerD.text = arrEurope[intRandomAnswerD][1];
}
switch(intRandomAnswerPosition)
{
case 0: answerA.text = arrEurope[intRandomMonument][1];
break;
case 1: answerB.text = arrEurope[intRandomMonument][1];
break;
case 2: answerC.text = arrEurope[intRandomMonument][1];
break;
case 3: answerD.text = arrEurope[intRandomMonument][1];
};
//als er antwoorden hetzelfde zijn, voor de gelijke een random blijven maken tot ze niet hetzelfde zijn
if(
[answerA.text isEqualToString: answerB.text]||
[answerA.text isEqualToString: answerC.text]||
[answerA.text isEqualToString: answerD.text]
){
answerA.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerB.text isEqualToString: answerA.text]||
[answerB.text isEqualToString: answerC.text]||
[answerB.text isEqualToString: answerD.text]
){
answerB.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerC.text isEqualToString: answerA.text]||
[answerC.text isEqualToString: answerB.text]||
[answerC.text isEqualToString: answerD.text]
){
answerC.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerD.text isEqualToString: answerA.text]||
[answerD.text isEqualToString: answerB.text]||
[answerD.text isEqualToString: answerC.text]
){
answerD.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
//Laat de afbeelding zien van het gekozen monument (via random gekozen)
imageContainer.image = [UIImage imageNamed: arrEurope[intRandomMonument][0]];
}
}
//hier onder zit ergens een fout want hij geeft precies random juist en fout :)
//kan zijn dat het opgelost is vanaf we niet 2x dezelfde vragen hebben maar ik denk het niet.
//press buttonA
-(IBAction)AnswerA {
if([answerA.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonB
-(IBAction)AnswerB {
if([answerB.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonC (works)
-(IBAction)AnswerC {
if([answerC.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonD
-(IBAction)AnswerD {
if([answerD.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//hier onder niets wijzigen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
NSUserDefaults *scores = [NSUserDefaults standardUserDefaults];
if (_points>[scores integerForKey :#"highscore"]) {
[_highScoresLabel setString:[NSString stringWithFormat:#"%d",_points]];
[scores setInteger:_points forKey:#"highscore"];
I'm using that code to show persistent highscore in one of my game.
to show in another UIViewController simply add this code where _higScoreLabel is the label ypu want the scores to be shown :
NSUserDefaults *scores = [NSUserDefaults standardUserDefaults];
NSString *_points = [scores integerForKey :#"highscore"];
[_highScoresLabel setString:[NSString stringWithFormat:#"%d",_points]];
As soon as you know what the user's final score was, write the integer to NSUserDefaults like:
[[NSUserDefaults standardUserDefaults] setInteger:intScore forKey:#"score"];
Then, in order to show the score integer in the other view controller, you'll need to just read the value from disk in viewDidLoad of the other viewController, and then set it in the label!
Since the value is already stored on disk, you don't even need to pass it as a parameter or set it as a property on the other viewcontroller, just read it from NSUserDefaults in viewDidLoad (or whatever/whereever method you need to set it).
So in the second viewcontroller, do:
- (void) viewDidLoad {
self.anotherLabel.text = [NSString stringWithFormat:#"%d", [defaults integerForKey:#"score"]];
}
// To save in pref
int highScore = yourGameScore;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:highScore] forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
// To get saved value from pref
int highScore = [[[NSUserDefaults standardUserDefaults] objectForKey:#"HighScore"] intValue ];
here is similar question in stack..
Try using NSUserDefaults ,it will keep the value in memory until you forcefully remove it or you delete the app.
int Score = HighScore;
[[NSUserDefaults standardUserDefaults] setObject:Score forKey:#"anyKey"];
currentScoreLabel.text = [NSString stringWithFormat:#"%d",Score];
highScoreLabel.text=[NSString stringWithFormat:#"%d",[[NSUserDefaults standardUserDefaults] objectForKey:#"anyKey"]];

wait for a method to finish before starting another

assume that i have two sequential methods, methodA and methodB (methodB is called at the end of methodA) and i need to finish completely with the process of methodA before starting methodB :
-(void)methodA {
//do some very heavy computation here
[self methodB];
}
-(void)methodB {
//this method performs some animation
}
methodA requires alot of processing power and takes time to finish while methodB has animations. The animations are starting laggy at first and im guessing this has to do with the overhead of method A. So how can i make the second method start only after the first has finished completely?
this is the actual code:
the code is very messy and unorganized. there is alot of code that has been commented out so please ingore that. I test some things sometimes and then comment them out incase i need them later.
here is what is happening: it starts with (void)checkMoves method. This method calls either one of two similar methods which are
-(void)getMovesForJourney:(int)journey withRolls:(NSArray *)rolls or
-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls
these methods are wrappers for a long recursive process (which is most probably where the multithreading is happening).
at the end of (void)checkMoves another method -(void)analyseMoves is called. This is also a heavy process.
and finally, at the end of -(void)analyseMoves the animation method -(void)move: is called. this last method is starting with a lag.
finally at the end of -(void)move: the process will start again until no more 'moves' are available.
the methods below are not in order so please refer to the description above to know whats going on.
-(void) checkMoves {
GameScene *game = [GameScene sharedGameScene];
CCLOG(#"start");
for (Stone *stone in stones) {
if (!stone.onBoard) {
if ([game EntryAvailable]) {
[self getEntryMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];
}
}
else {
[self getMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];
}
}
CCLOG(#"finish");
[self analyseMoves];
}
-(NSMutableArray *) otherPlayerLocations {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
Player *otherPlayer = [game playerOne];
NSMutableArray *locations = [[[NSMutableArray alloc] init] autorelease];
for (Stone *stone in otherPlayer.stones) {
if (stone.journey < 77) {
int location;
if (stone.onBoard)
location = [[board tileForATag:[self convertJourneyToTileTag:stone.journey]] bTag];
else
location = 0;
[locations addObject:[NSNumber numberWithInt:location]];
}
}
return locations;
}
-(void) analyseMoves {
if (moves.count > 0) {
NSMutableArray *killMoves = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *safeMoves = [[[NSMutableArray alloc] init] autorelease];
int mostThreatened;
float highestThreat = -1.0;
float lowestThreat = 100.0;
AIMove *safestMove;
//get kill and safe moves in seperate arrays
for (AIMove *move in moves) {
if (move.moveType == killMoveType)
[killMoves addObject:move];
else if (move.moveType == safeMoveType)
[safeMoves addObject:move];
// get highest threatened stone
//if (move.potThreat > highestThreat) {
// mostThreatened = move.journey;
// highestThreat = move.potThreat;
if (move.initThreat < lowestThreat) {
lowestThreat = move.initThreat;
safestMove = [move copy];
CCLOG(#"safest move assigned");
}
//}
}
//MOVE SELECTION:
//___________________________________
//choose best kill move
int killJourney;
if (killMoves.count > 0) {
//leave one move in killMoves with highest journey
killJourney = [[killMoves objectAtIndex:0] tileTag];
for (AIMove *killMove in killMoves) {
if (killMove.tileTag < killJourney)
[killMoves removeObject:killMove];
else
killJourney = killMove.tileTag;
}
}
//select correct move
if (killMoves.count > 0) {
[self move:[killMoves objectAtIndex:0]];
CCLOG(#"Kill move chosen");
}
else {
CCLOG(#"this is called!!!!");
CCLOG(#"safest move with initThreat: %i, potThreat: %i",safestMove.journey, safestMove.tileTag);
[self move:safestMove];
CCLOG(#"Success");
}
/*
else if (safeMoves.count > 0) {
[self move:[safeMoves objectAtIndex:0]];
CCLOG(#"safe move chosen");
}
else {
//temp random move generation
randomMove = CCRANDOM_0_1()*[moves count];
AIMove *move = [moves objectAtIndex:randomMove];
[self move:move];
CCLOG(#"Random move chosen");
}
*/
}
}
-(void) assignThreatLevel:(AIMove *)move {
NSArray *otherPlayerStones = [self otherPlayerLocations];
NSMutableArray *initThreats = [[NSMutableArray alloc] init];
NSMutableArray *potThreats = [[NSMutableArray alloc] initWithCapacity:4];
for (NSNumber *location in otherPlayerStones) {
//get threat levels for potential moves
if (move.tileTag > [location intValue]) {
int dif = move.tileTag - [location intValue];
CCLOG(#"dif: %i",dif);
//threat level conditions:
// 1 >> 5 = 70% of journey
// 6 >> 9 = 40% of journey
// 10 & 11 = 50% of journey
// 12 >> 24 = 20% of journey
// 25 && 26 = 50% of journey
// 27+ = 20% of journey
if (move.tileTag < 9) {
[initThreats addObject:[NSNumber numberWithFloat:0.0f]];
}
else if (dif >= 1 && dif <= 5) {
[initThreats addObject:[NSNumber numberWithFloat:k1to5]];
}
else if (dif >= 6 && dif <= 9) {
[initThreats addObject:[NSNumber numberWithFloat:k6to9]];
}
else if (dif == 10 || dif == 11) {
[initThreats addObject:[NSNumber numberWithFloat:k10to11]];
}
else if (dif >= 12 && dif <= 24) {
[initThreats addObject:[NSNumber numberWithFloat:k12to24]];
}
else if (dif == 25 || dif == 26) {
[initThreats addObject:[NSNumber numberWithFloat:k25to26]];
}
else if (dif > 26) {
[initThreats addObject:[NSNumber numberWithFloat:k27plus]];
}
//-------------------------------------
}
//get Threat levels for current positions
if (move.tileTag > [location intValue]) {
int dif = move.tileTag - [location intValue];
//threat level conditions:
// 1 >> 5 = 70% of journey
// 6 >> 9 = 40% of journey
// 10 & 11 = 50% of journey
// 12 >> 24 = 20% of journey
// 25 && 26 = 50% of journey
// 27+ = 20% of journey
if (move.journey < 8 || move.journey > 75)
[potThreats addObject:[NSNumber numberWithFloat:0.0f]];
else if (dif >= 1 && dif <= 5)
[potThreats addObject:[NSNumber numberWithFloat:k1to5]];
else if (dif >= 6 && dif <= 9)
[potThreats addObject:[NSNumber numberWithFloat:k6to9]];
else if (dif == 10 || dif == 11)
[potThreats addObject:[NSNumber numberWithFloat:k10to11]];
else if (dif >= 12 && dif <= 24)
[potThreats addObject:[NSNumber numberWithFloat:k12to24]];
else if (dif == 25 || dif == 26)
[potThreats addObject:[NSNumber numberWithFloat:k25to26]];
else if (dif > 26)
[potThreats addObject:[NSNumber numberWithFloat:k27plus]];
//-------------------------------------
}
}
float initThreat = 0.0f;
float potThreat = 0.0f;
for (NSNumber *number in initThreats) {
if ([number floatValue] > initThreat)
initThreat = [number floatValue];
}
for (NSNumber *number in potThreats) {
if ([number floatValue] > potThreat)
potThreat = [number floatValue];
}
move.initThreat = initThreat;
move.potThreat = potThreat;
[initThreats release];
}
-(void) move:(AIMove *)move {
CCLOG(#"Moves count: %i",[moves count]);
if ([moves count] > 0) {
BOOL isOtherStoneOnPreviousTile = NO;
int total;
if (move.tileTag > 8)
total = move.tileTag - move.journey;
else if (move.tileTag < 9 && move.journey > 8)
total = ((9-move.tileTag)+75) - move.journey;
else if (move.tileTag < 9)
total = move.tileTag - move.journey;
CCLOG(#"Total: %i",total);
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
BoardTile *tile = [[game board] tileForBTag:move.tileTag];
CCSequence *sequence;
NSMutableArray *actions = [[[NSMutableArray alloc] init] autorelease];
id delay = [CCDelayTime actionWithDuration:0.5];
[actions addObject:delay];
if (move.journey > 0) {
for (int i = 1; i < total+1; i++) {
if (move.journey+i < 76)
tile = [board tileForBTag:move.journey+i];
else
tile = [board tileForBTag:9-((move.journey+i)-75)];
id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
[actions addObject:moveAction];
}
}
else {
id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
[actions addObject:moveAction];
}
// id moveFunc = [CCCallFunc actionWithTarget:self selector:#selector(moveMotion)];
//id moveAction = [CCMoveTo actionWithDuration:0.3 position:tile.position];
id killFunc = [CCCallFuncND actionWithTarget:self selector:#selector(killStonesForTile:data:) data:tile];
//id callfunc = [CCCallFunc actionWithTarget:self selector:#selector(move)];
[actions addObject:killFunc];
//[actions addObject:callfunc];
sequence = [CCSequence actionMutableArray:actions];
[actions removeAllObjects];
CGPoint exitPos = ccp(exitPosition.x-(completeStones*30),exitPosition.y-(completeStones*30));
id move2 = [CCMoveTo actionWithDuration:0.2f position:exitPos];
id sequence2 = [CCSequence actions:move2, nil];
Stone *stone = [self getStoneForJourney:move.journey];
//-
//------------------------------------------
//clean tracks
for (Stone *stone in stones) {
if (stone.journey == (move.tileTag - move.journey))
isOtherStoneOnPreviousTile = YES;
}
if (!isOtherStoneOnPreviousTile) {
BoardTile *prevTile = [board tileForBTag:[self convertJourneyToTileTag:move.journey]];
prevTile.occupiedBy = 0;
}
//===========================================
//-------------------------------------------
//set stone status
if (move.tileTag < 9 && stone.crossedEntry)
stone.journey = (9 - move.tileTag) + 75;
else
stone.journey = move.tileTag;
stone.onBoard = YES;
tile.occupiedBy = player2;
if (stone.journey > 8 && !stone.crossedEntry)
stone.crossedEntry = YES;
//============================================
if (stone.journey < 84)
[stone runAction:sequence];
else {
[stone runAction:sequence2];
completeStones++;
stone.isJourneyComplete = YES;
}
CCLOG(#"Stone Journey:%i",stone.journey);
NSArray *rollTypesArray = [move rollTypes];
[self removeRollTypes:rollTypesArray];
[moves removeAllObjects];
[game updateRollResults];
[self updateMoveAvailability];
}
else {
GameScene *game = [GameScene sharedGameScene];
[moves removeAllObjects];
[game nextTurn];
[game updateRollResults];
}
}
-(Stone *)getStoneForJourney:(int)journey {
Stone *theStone;
for (Stone *stone in stones) {
if (stone.journey == journey)
theStone = stone;
}
return theStone;
}
-(void)dealloc {
[moves release];
[rollTypes release];
[results release];
[super dealloc];
}
-(void)killStonesForTile:(id)sender data:(BoardTile *)tile {
GameScene *game = [GameScene sharedGameScene];
int tileTag;
Player *otherPlayer;
if (playerNumber == player1) {
tileTag = tile.aTag;
otherPlayer = [game playerTwo];
}
else {
tileTag = tile.bTag;
otherPlayer = [game playerOne];
}
CCArray *currentStones = [otherPlayer stones];
for (Stone *stone in currentStones) {
if (!stone.isJourneyComplete) {
int journey = stone.journey;
if (tileTag == tile.aTag) {
if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.bTag) {
CCLOG(#"blue stone killed");
[self returnStoneToOrigin:stone];
}
}
if (tileTag == tile.bTag) {
if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.aTag) {
CCLOG(#"gold stone killed");
[self returnStoneToOrigin:stone];
}
}
}
}
}
-(void)removeRollTypes:(NSArray *)theRollTypes {
GameScene *game = [GameScene sharedGameScene];
NSMutableArray *rolls = [game rolls];
for (NSNumber *roll in theRollTypes) {
NSUInteger index = [rolls indexOfObject:[game convertIntToRoll:roll]];
CCLOG(#"rolltypes count: %i",[theRollTypes count]);
CCLOG(#"roll integer: %i",[roll intValue]);
[rolls removeObjectAtIndex:index];
}
}
#pragma mark -
#pragma mark enumerations
- (NSArray*)getSums:(NSArray*)numbers {
NSMutableArray *result = [self getSumsHelper:numbers startingFrom:0];
[result removeObjectAtIndex:0];
return result;
}
- (NSMutableArray*)getSumsHelper:(NSArray*)numbers startingFrom:(NSUInteger)index {
/* (1) */
if (index >= [numbers count])
return [NSMutableArray arrayWithObject:[NSNumber numberWithFloat:0]];
/* (2) Generate all the subsets where the `index`th element is not included */
NSMutableArray* result = [self getSumsHelper:numbers startingFrom:index+1];
// NSSortDescriptor *mySorter = [[NSSortDescriptor alloc] initWithKey:#"floatValue" ascending:YES];
// [result sortUsingDescriptors:[NSArray arrayWithObject:mySorter]];
/* (3) Add all the cases where the `index`th element is included */
NSUInteger i, n = [result count];
float element = [[numbers objectAtIndex:index] floatValue];
for (i = 0; i < n; i++) {
float element2 = [[result objectAtIndex:i] floatValue];
float sum = element+element2;
BOOL numberPresent = NO;
for (NSNumber *number in result) {
if ([number floatValue] == sum)
numberPresent = YES;
}
if (!numberPresent)
[result addObject:[NSNumber numberWithFloat:sum]];
}
return result;
}
-(NSArray *) getCombsforNumbers:(NSArray *)numbers withTarget:(int)target{
NSMutableArray *partial = [[NSMutableArray alloc] init];
[partial addObject:[NSNumber numberWithInt:0]];
[results removeAllObjects];
NSArray *result = [self getCombsHelper:numbers target:target partial:partial];
NSUInteger minCount = [[result objectAtIndex:0] count];
NSUInteger index = 0;
NSMutableArray *combArray = [result objectAtIndex:0];
for (NSMutableArray *array in result) {
if ([array count] < minCount) {
minCount = [array count];
index = [result indexOfObject:array];
combArray = array;
}
}
//remove number 0 from array
[combArray removeObject:[NSNumber numberWithInt:0]];
return combArray;
}
-(NSMutableArray *) getCombsHelper:(NSArray *)numbers target:(int)target partial:(NSMutableArray *)partial {
int s = 0;
for (NSNumber *number in partial) {
s += [number intValue];
}
if (s == target) {
[results addObject:partial];
}
if (s >= target) {
return results;
}
for (int i = 0; i < [numbers count]; i++) {
NSMutableArray *remaining = [[[NSMutableArray alloc] init] autorelease];
int n = [[numbers objectAtIndex:i] intValue];
for (int j = i+1; j<[numbers count]; j++) {
[remaining addObject:[numbers objectAtIndex:j]];
}
NSMutableArray *partialRec = [[[NSMutableArray alloc] init] autorelease];
[partialRec addObjectsFromArray:partial];
[partialRec addObject:[NSNumber numberWithInt:n]];
[self getCombsHelper:remaining target:target partial:partialRec];
}
return results;
}
-(void) getMovesForJourney:(int)journey withRolls:(NSArray *)rolls {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
NSArray *sums = [self getSums:rolls];
for (NSNumber *number in sums) {
if ([number intValue]+journey <= 84) {
BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
if (tile.isSafeTile) {
if (tile.occupiedBy != player1) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
//----------------------------------
move.moveType = safeMoveType;
move.initThreat = 0.0;
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
}
}
else {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
//-----------------------------------
[move setRollTypes:theRollTypes];
//assing threat level
[self assignThreatLevel:move];
CCLOG(#"move initThreat: %f",move.initThreat);
//check for kill move
NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
for (NSNumber *location in otherPlayerPositions) {
if (move.tileTag == [location intValue])
move.moveType = killMoveType;
}
[moves addObject:move];
}
}
//int i = [number intValue];
//NSArray *combs = [self getCombsforNumbers:numbers withTarget:i];
}
}
-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
NSArray *sums = [self getSums:rolls];
for (NSNumber *number in sums) {
if ([number intValue]+journey <= 84) {
BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
if (tile.isSafeTile) {
if (tile.occupiedBy != player1) {
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
BOOL containsEntry = NO;
for (NSNumber *rollType in theRollTypes) {
if ([rollType intValue] == 1) {
containsEntry = YES;
}
}
if (containsEntry) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
move.moveType = safeMoveType;
move.initThreat = 0.0;
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
//----------------------------------
}
}
}
else {
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
BOOL containsEntry = NO;
for (NSNumber *rollType in theRollTypes) {
if ([rollType intValue] == 1) {
containsEntry = YES;
}
}
if (containsEntry) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
[move setRollTypes:theRollTypes];
//check for kill move
NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
for (NSNumber *location in otherPlayerPositions) {
if (move.tileTag == [location intValue])
move.moveType = killMoveType;
}
//assing threat level
[self assignThreatLevel:move];
[moves addObject:move];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
//----------------------------------
}
}
}
}
}
Technically, methodB is called after methodA is finished. In methodA you are apparently doing things that are backgrounded, meaning that the method finishes while some tasks are performed on another thread (or scheduled on the runloop). There's nothing we can say about this unless you do share the inner workings of methodA.