您的位置:首页 > 编程语言 > Go语言

Gomoku五子棋OC实现

2015-10-29 13:19 507 查看
最近有朋友在学习UI,想制作一个简单的五子棋来练手,但不知道思路,我就写了一个五子棋来作为引导吧。

提到五子棋,首先就是得考虑到一个棋盘的问题,由于朋友是初学UI,所以在棋盘布局上就是用了view的方法创建了棋盘,tableView等方法应该会更好一些,感兴趣的朋友可以去学习学习相关知识。五子棋是15 x 15的布局,代码实现如下
for (int i = 0; i < 15; i++) {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(45, 100 + i * 20, 280, 1)];
view.backgroundColor = [UIColor blackColor];
[self.view addSubview:view];
[view release];
for (int j = 0; j < 15; j++) {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(45 + j * 20, 100, 1, 280)];
view.backgroundColor = [UIColor blackColor];
[self.view addSubview:view];
[view release];
}
}


实际效果如图



有了棋盘之后就是落子的问题,实际上,本程序采用的并不是真正意义上得“落子”,而是在每个可以落子的点预设了没有初始化颜色的button,通过button点击事件来改变button的颜色,达到实际落子的效果,预设棋子代码如下
//    预设棋子
for (int i = 0 ; i < 15; i++) {
for (int j = 0; j < 15; j++) {
UIButton *chess = [UIButton buttonWithType:UIButtonTypeSystem];
chess.frame = CGRectMake(45 + 20 * j, 100 + 20 * i, 18, 18);
chess.center = CGPointMake(45 + 20 * j, 100 + 20 * i);
chess.layer.cornerRadius = 9;
chess.layer.masksToBounds = YES;
[chess addTarget:self action:@selector(playChess:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:chess];
[chess release];

[_dataSource addObject:@"empty"];
}
}
该程序没有使用自定义视图,但是吧每个棋子需要有自己的属性,也就是“没被点击empty”, “黑子black”, 和“白子white”, 这些属性我通过创建一个可变数组_dataSource的属性来存储,方便管理。同时,五子棋还需判断当前回合是黑子还是白子的回合,我定义了一个flag属性来标记回合。基本逻辑是当点击某个落子点的时候,如果该落子点有白子,则该落子点为“white”,
如果为黑子,则为“black”,如果没有子,则为“empty”, 说明该处可以放置棋子 ,根据放置棋子的颜色,向用于存储棋盘棋子信息的可变数组_dataSource传值,代码实现如下
if (_flag) {
sender.backgroundColor = [UIColor blackColor];
[_dataSource replaceObjectAtIndex:(15 * y + x) withObject:@"black"];
_labelTurn.text = @"white turn";
} else {
sender.backgroundColor = [UIColor whiteColor];
[_dataSource replaceObjectAtIndex:(15 * y + x) withObject:@"white"];
_labelTurn.text = @"black turn";
}
_flag = !_flag;
至此,基本的棋盘和落子功能已经实现了,现在需要判断的是赢得比赛的逻辑。一个比较通行的方法是每次落子完成后对这个数组横向,纵向,斜向四个方向分别遍历,找到至少五个值相同的即为获胜,返回数组内存储的值即可。在这里,每次落子都遍历数组效率太低,考虑每次落子对该子周围的棋子进行遍历,提高程序效率,代码如下
//        向右
int xRight = x + 1;
int yRight = y;
int countRight = 0;
while ([_dataSource[15 * yRight + xRight] isEqualToString:_dataSource[15 * y + x]]) {
countRight++;
xRight++;
if (xRight >= 15) {
break;
}
}

//        左上
int xLeftUp = x - 1;
int yLeftUp = y - 1;
int countLeftUp = 0;
while ([_dataSource[15 * yLeftUp + xLeftUp] isEqualToString:_dataSource[15 * y + x]]) {
countLeftUp++;
xLeftUp--;
yLeftUp--;
if (xLeftUp < 0 || yLeftUp < 0) {
break;
}
}

//        右下
int xRightDown = x + 1;
int yRightDown = y + 1;
int countRightDown = 0;
while ([_dataSource[15 * yRightDown + xRightDown] isEqualToString:_dataSource[15 * y + x]]) {
countRightDown++;
xRightDown++;
yRightDown++;
if (xRightDown >= 15 || yRightDown >= 15) {
break;
}
}

//        右上
int xRightUp = x + 1;
int yRightUp = y - 1;
int countRightUp = 0;
while ([_dataSource[15 * yRightUp + xRightUp] isEqualToString:_dataSource[15 * y + x]]) {
countRightUp++;
xRightUp++;
yRightUp--;
if (xRightUp >= 15 || yRightUp < 0) {
break;
}
}

//        左下
int xLeftDown = x - 1;
int yLeftDown = y + 1;
int countLeftDown = 0;
while ([_dataSource[15 * yLeftDown + xLeftDown] isEqualToString:_dataSource[15 * y + x]]) {
countLeftDown++;
xLeftDown--;
yLeftDown++;
if (xLeftDown < 0 || yLeftDown >= 15) {
break;
}
}

//        判断输赢
if ((countUp + countDown >= 4) || (countLeft + countRight >= 4) || (countLeftDown + countRightUp >= 4) || (countRightDown + countLeftUp >= 4)) {
NSLog(@"%@ win", _dataSource[15 * y + x]);
_labelWin.text = [_dataSource[15 * y + x] stringByAppendingString:@" win"];
当然,可以考虑使用递归来获取count,有兴趣的朋友可以自己尝试。

至此,游戏的判断功能也有了,但是在一方获胜之后程序依旧能够继续执行,需要对游戏结束做一个控制,这里用的是将所有棋子信息都改成了获胜子的信息,代码如下

//            游戏结束后不再能够落子
for (int i = 0; i < 225; i++) {
[_dataSource replaceObjectAtIndex:i withObject:_labelWin.text];
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: