Swift数独游戏优化——C++与OC混编、plist自动生成
一、为什么要C++与OC混编?
在我之前的数独游戏中涉及到的数独游戏生成算法是参考的网上其他人的算法,是利用C++来实现的。
但是在我的例子中我发现这样存在一定的局限性:
1、我是利用Terminal的重定向功能来实现输出的,这样不能查看程序的实际运行状态信息。
2、C++编写的代码不能直接生成plist文件,而OC有直接的API可以生成plist文件。(当我前几天刚知道的时候我感觉之前用C++生成plist是有多勇敢)
二、如何进行C++与OC混编?
1、OC文件后缀改为“mm”
2、混编下涉及OC的语法要写在 “#import <Foundation/Foundation.h>”之后
三、注意点:
关于OC开发中的文件后缀名区别m,mm,cpp,h
1)文件区别:
.h :头文件。头文件包含类,类型,函数和常数的声明。    
.m :源代码文件。这是典型的源代码文件扩展名,可以包含Objective-C和C代码。     
.mm :源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名
.cpp:只能编译C++
当你需要在源代码中包含头文件的时候,你可以使用标准的#include编译选项,但是Objective-C提供了更好的方法。#import选项和#include选项完全相同,只是它可以确保相同的文件只会被包含一次。Objective-C的例子和文档都倾向于使用#import。
.m 和.mm 的区别是告诉gcc 在编译时要加的一些参数。当然.mm还可以命名成.m,但在编译时要手动加参数(麻烦)
2)常用场景:
如果你的OC代码里面有包含C++的引用或代码,将此类更改为.mm即可;
3)例子:
ERROR:./zxing/cpp/core/src/zxing/common/Counted.h:21:10: 'iostream' file not found
在引用zxing的时候#import<QRCodeReader.h>用到了iostream,但是它是/iphoneOS6.1/user/include/c++下面的类,故需要把类名改为.mm即可
注意#import或#include的位置要在.mm文件里,如果在.h头文件里是没用的
四、具体到数独游戏的例子,最后的混编代码如下:
main.mm
1: //
2: // main.m
3: // sudokuGenerater
4: //
5: // Created by 张泽阳 on 4/9/15.
6: // Copyright (c) 2015 张泽阳. All rights reserved.
7: //
8:
9:
10: #include <fstream>
11: #include <unistd.h>
12: #include "stdio.h"
13: #include "stdlib.h"
14: #include "time.h"
15: //#include "fstream.h"
16: #include <iostream>
17: #include <sstream>
18: #include <string>
19:
20: using namespace std;
21: ostringstream oss;
22: ostringstream coutt;
23: string currentS;
24: class CSudoku
  25:  {
26: int map[9][9],lastmap[9][9];
27: int smod;
28: int solves;
29: int check(int,int,int*);
30: void dfs();
31: public:
  32:      enum{ANY=0,ALL=1};
33: CSudoku(int n=40);// 随机生成数独,n越大越难
34: CSudoku(int *data);// 人工指定数独
35:
36: string display();// 显示数独
37: void Sdisplay();// 显示数独
38: int resolve(int mod=ALL);// 解数独
39: };
40: long sand=0;
41:
42:
43: CSudoku::CSudoku(int n)
  44:  {
45: int i,j;
46: sand++;
47: srand(time(&sand));
48: do
  49:      {
50: for(i=0;i<9;++i)
  51:          {
52: for(j=0;j<9;++j)
53: map[i][j]=0;
54: j=rand()%9;
55: map[i][j]=i+1;
56: }
57: }
58: while(!resolve(ANY));
59:
60: // 挖窟窿
61: for(int k=0;k<n;)
  62:      {
63: i=rand()%81;
64: j=i%9;
65: i=i/9;
66: if(map[i][j]>0)
  67:          {
68: map[i][j]=0;
69: ++k;
70: }
71:
72: }
  73:      //printf("(randomized sudoku created with %d blanks.)\n",blanks);
74: }
75: CSudoku::CSudoku(int *data)
  76:  {
77: int *pm=(int*)map;
78: for(int i=0;i<81;++i)
79: pm[i]=data[i];
80: }
81: void addS();
82: string CSudoku::display()
  83:  {
84: ostringstream osst;
  85:      osst.str("");
86: // osst<<"<string>";
87: for(int i=0;i<9;++i)
  88:      {
89: for(int j=0;j<9;++j)
  90:          {
91: // if(map[i][j]>0)
  92:              //                printf("< %d >  ",map[i][j]);
93: // else
  94:              //                printf("[   ]  ");
95:
96: osst<<map[i][j];
97: }
  98:          //        printf("\n");
99: }
100: // osst<<"</string>\n";
101: // oss<<osst.str();
102: return osst.str();
103: }
104: int same = 1;
105: void sameLog();
106: void CSudoku::Sdisplay()
 107:  {
108: ostringstream osst;
 109:      osst.str("");
110: // osst<<"<string>";
111: same = 1;
112: for(int i=0;i<9;++i)
 113:      {
114: for(int j=0;j<9;++j)
 115:          {
 116:              if (map[i][j]!=lastmap[i][j]) {
117: same = 0;
118: }
119: }
120: }
 121:      if (same) {
122: sameLog();
123: // same = 0;
124: return;
125: }
126: for(int i=0;i<9;++i)
 127:      {
128: for(int j=0;j<9;++j)
 129:          {
130: lastmap[i][j] = map[i][j];
131: osst<<map[i][j];
132: }
133: }
134: // osst<<"</string>\n";
135: // oss<<osst.str();
136: currentS = osst.str();
137: addS();
138: }
139: int CSudoku::resolve(int mod)
 140:  {
141: smod=mod;
142: if(mod==ALL)
 143:      {
144: solves=0;
145: dfs();
146: return solves;
147: }
148: else if(mod==ANY)
 149:      {
150: try
 151:          {
152: dfs();
153: return 0;
154: }
155: catch(int)
 156:          {
157: return 1;
158: }
159: }
160: return 0;
161: }
162: int CSudoku::check(int y,int x,int *mark)
 163:  {
164: int i,j,is,js,count=0;
165: for(i=1;i<=9;++i)
166: mark[i]=0;
167: for(i=0;i<9;++i)
168: mark[map[y][i]]=1;
169: for(i=0;i<9;++i)
170: mark[map[i][x]]=1;
171: is=y/3*3;
172: js=x/3*3;
173: for(i=0;i<3;++i)
 174:      {
175: for(j=0;j<3;++j)
176: mark[map[is+i][js+j]]=1;
177: }
178: for(i=1;i<=9;++i)
179: if(mark[i]==0)
180: count++;
181: return count;
182: }
183: int toomanys = 0; int blanks = 40;
184: void CSudoku::dfs()
 185:  {
186: int i,j,im=-1,jm=0,min=10;
187: int mark[10];
188: for(i=0;i<9;++i)
 189:      {
190: for(j=0;j<9;++j)
 191:          {
192: if(map[i][j])
193: continue;
194: int c=check(i,j,mark);
195: if(c==0)
196: return;
197: if(c<min)
 198:              {
199: im=i;
200: jm=j;
201: min=c;
202: }
203: }
204: }
205: if(im==-1)
 206:      {
207: if(smod==ALL)
 208:          {
209: ++solves;
 210:              //            printf("No. %d:\n",++solves);
 211:              if (solves>(2)) {
212: toomanys = 1;
213: return;
214: }
215: Sdisplay();
216: return;
217: }
218: else if(smod==ANY)
 219:          {
220: throw(1);
221: }
222:
223: }
224: check(im,jm,mark);
225: for(i=1;i<=9;++i)
 226:      {
227: if(mark[i]==0)
 228:          {
229: map[im][jm]=i;
230: dfs();
231: }
232: }
233: map[im][jm]=0;
234: }
235:
236:
237: #import <Foundation/Foundation.h>
238: //#import "ref.mm"
239: NSMutableArray* eachSArray ;
240: /**
241: * 混编下涉及OC的语法要写在 “#import <Foundation/Foundation.h>”之后
242: *
243: */
 244:  void addS(){
245: [eachSArray addObject:[NSString stringWithFormat:@"%s",currentS.c_str()]];
246: }
 247:  void sameLog(){
248: NSLog(@"same!!!!!!");
249: }
 250:  int main(int argc, const char * argv[]) {
 251:      @autoreleasepool {
252: //得到完整的文件名
253: NSString *filename=[@"/Users/zhangzeyang/Desktop/" stringByAppendingString:@"R.plist"];
254: NSMutableDictionary *data = [[NSMutableDictionary alloc]init];
255: int num = 0;
 256:          while (blanks<71) {
257: NSLog(@"\n------------blanks = %d------------\n",blanks);
258: // coutt<<"<key>D"<<blanks<<"</key>"<<endl<<"<array>"<<endl;
259: NSMutableArray* eachDArray = [[NSMutableArray alloc]init];
260: int inNum = 0;
 261:  //            for (int ii = 0; ii + blanks <120; ++ii) {
 262:               for (int ii = 0; ii < 34 - blanks / 10; ++ii) {
263: NSLog(@"blanks = %d num = %d ii = %d",blanks,num,ii);
264:
265: same = 1;toomanys = 0;
266: // oss<<"<dict>"<<endl<<"<key>p</key>"<<endl;
267: NSMutableDictionary* eachPassDic = [[NSMutableDictionary alloc]init];
268: CSudoku s(blanks);
269: string ppp = s.display();
270: [eachPassDic setValue:[NSString stringWithFormat:@"%s",ppp.c_str()] forKey:@"p"];
271: eachSArray = [[NSMutableArray alloc]init];
272:
273: // oss<<"<key>s</key>"<<endl<<"<array>"<<endl;
274: s.resolve();
275: // oss<<"</array>"<<endl<<"</dict>"<<endl;
 276:                  if (same){
 277:                      oss.str("");
278: continue;
 279:                  }else{
280: // coutt<<oss.str();
 281:                      oss.str("");
282: [eachPassDic setValue:eachSArray forKey:@"s"];
283: [eachDArray addObject:eachPassDic];
284: ++num;++inNum;
285: }
 286:                  if (inNum>30) {
287: break;
288: }
289: }
290: // coutt<<"</array>"<<endl;
 291:              if (inNum ) {
292: // cout<<coutt.str();
293: [data setValue:eachDArray forKey:[NSString stringWithFormat:@"D%d",blanks]];
294: }
 295:              coutt.str("");
 296:              oss.str("");
297: blanks+=1;
298:
299: }
300:
301: // cout<<"</dict>\n</plist>\n";
302: //输入写入
303: [data writeToFile:filename atomically:NO];
304: }
305: return 0;
306: }
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
六、涉及到的其他知识
1)string转char*
char* s = str.c_str();.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }即可
参考链接:
http://blog.csdn.net/totogo2010/article/details/7634185
http://blog.csdn.net/penuel/article/details/9796721
http://www.cnblogs.com/zhixing/archive/2013/06/04/3116814.html
http://m.blog.csdn.net/blog/woshiwls/17272621
Swift数独游戏优化——C++与OC混编、plist自动生成的更多相关文章
- iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法
		
1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...
 - Swift & OC 混编 浅析
		
转载自:http://www.infoq.com/cn/articles/wangyi-cartoon-swift-mixed-practice?utm_campaign=rightbar_v2&am ...
 - cocoapod Podfile use frameworks swift/oc混编 could not build module xxx
		
前置: 知名的pod: AFNetworking 我自己的pod: AFNetworking+RX 3.1.0.18 里面有一段代码是: #import <Foundation/Founda ...
 - swift c++ oc 混编
		
http://www.tuicool.com/articles/QZNrErM iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较 时间 2015-03-23 23 ...
 - iOS8开发~Swift(五)Swift与OC混编
		
一.概要 首先看<The Swift Programming Language>中提到"Swift's compatibility with Objective-C lets y ...
 - swift与OC混编之调用函数
		
在桥接头文件里#import oc的.h文件,整个swift工程都能使用该oc文件,在.h里暴露的方法都能被该工程使用 //oc文件 TestOC.h #import @interface TestO ...
 - iOS 静态类库 打包 C,C++文件及和OC混编
		
iOS 静态类库 编译 C,C++ 我们都知道,OC 原生支持C, 在 创建的 OC类的 .m 里面,可以直接编写C的代码: 同样 Xcode 也支持 OC ,C++的混编,此时,我们通常把OC创建的 ...
 - iOS之 C++与oc混编
		
声明:本文只是随笔,自己做个笔记方便以后查阅如要转载,注明出处.谢谢! 2016年第一篇随笔!!! 由于最近要搞一个项目用到c++的一些api所以要混编,于是就记录下这个过程中的一些细节上的东西! O ...
 - Swift与OC混编
		
OC调用Swift的方法:添加 import "xxxx-Swift.h" 头文件即可 Swift调用OC的方法:需要建立桥接: xxxx-Bridging-Header.h 头文 ...
 
随机推荐
- Eclipse开发环境配置,打磨Eclipse,安装插件(适用3.4,3.5,3.6,3.7)
			
转载自:http://elf8848.iteye.com/blog/354035 打磨Eclipse -- 磨刀不误砍柴工 -------------------------------------- ...
 - php魔术方法的使用
			
本文测试环境为 php5.5.12 一.__get .__set 将对象的属性进行接管. 一般来说,总是把类的属性定义为private,但是对属性的读取和赋值操作非常频繁,在php5+,预定义__se ...
 - python最简单发送邮件
			
#!/usr/bin/env python #coding:utf8 #Author:lsp #Date:下午5:51:13 #Version:0.1 #Function: #导入smtplib和MI ...
 - JAVA程序打包成exe文件详细图解
			
我们都知道Java可以将二进制程序打包成可执行jar文件,双击这个jar和双击exe效果是一样一样的,但感觉还是不同.其实将java程序打包成exe也需要这个可执行jar文件. 准备: eclipse ...
 - unity中绘制战争迷雾
			
接上一篇中说的游戏,我们已经实现了client.host上的一个物体可见不可见的行为.之后我们可以加入类似检查两个单位之间的距离.或是两个单位之间有无阻挡物来进一步实现游戏机制. 在这篇随笔中我会首先 ...
 - 使用QML创建第一个界面(转)
			
原文转自 https://blog.csdn.net/rl529014/article/details/51378307 在Qt编程中,我们可以使用纯C++代码,或C++和XML结合的方式来创建GUI ...
 - 24式太极拳:3D动画演示(图文)
			
http://blog.sina.com.cn/s/blog_4be33b740102e9ae.html 24式太极拳:3D动画演示(图文) (2013-03-10 18:45:55) 转载▼ 标签: ...
 - Launcher3无图标问题
			
MTK8382/8121平台. 机器(8寸,默认竖屏)第一次烧录完成后,以横放姿势启动,发现Launcher没有图标,而竖屏启动是没有这个问题的.在测试过程中发现,在设置中clear data后也会有 ...
 - mininet+floodlight搭建sdn环境并创建简单topo
			
第一步:安装git sudo apt-get update sudo apt-get install git 测试git是否安装成功: git 第二步:安装mininet 1.获取mininet最新源 ...
 - Git-回滚操作
			
git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit git log 查询回滚版本唯一commit标识代码 git reset --ha ...