所以要在每个格子内预先塞入9个标记数字,仅数独格子算下来就有9*9*9=729个格子且存在大量嵌套(这导致我在操作Storyboard时每一个修改都要等待至少20s)
(0)我们先在Storyboard中建一个viewcontroller,取名为Game。再在xcode左边新建一个Swift类,取名GameViewController,继承ViewController。将Storyboard中的Game属性中的父类设置成刚刚创建的GameViewController。
如图,选择中间那个两个圈圈的视图,右击我们刚刚创建好的UnitCell,将该UnitCell的TouchUpInside指向GameViewController中的空白处,如图
具体里面写什么现在不着急,后面才会用到。之所以现在就设置,是因为一会要复制这个UnitCell,复制新的UnitCell,你创建的点击事件关系也会一起复制过去。避免麻烦。
196*196,每个格子是一个UnitCell,设置颜色如图,这里的UnitCell注意要重新设置TouchUpInside事件,我们取名为onTouchMarkerUnitCell,并加上outlet方便调取。
1: //
2: // ViewController.swift
3: // sudoku-v02
4: //
5: // Created by 张泽阳 on 2/13/15.
6: // Copyright (c) 2015 张泽阳. All rights reserved.
7: //
8:
9: import UIKit
10: class ViewController: UIViewController,remainProtocol,UIAlertViewDelegate {
11: // MARK: - 变量
12: // var pickedNumberArray = Array <Array <Int>> ()
13: // var pickedMarkerArray = Array <Array <String>> ()
14: var currentPickingUnitCell:UnitCell? = nil
15: var prePass = pass(mytitle: "", isPassed: false, prob: "", solves: [""])
16: // var cellTemp:UITableViewCell?
17: // var preInitials:Array <Array <Int>> = Array <Array <Int>>()
18: var remainCells = 81
19: var isSucc = false
20: var notErr = true
21: var remainCellsCounter:RemainCellsCounter? = nil
22: // var unavailableNums = Array <Bool> ()//标记每次不可选的数字 如果选的话就错了
23: // var errPosition = Array<(Int,Int)>()
24: // MARK: - 实现代理方法,处理成功时的方法
25: func remainZero() {
26: if notErr {succ()}
27: }
28: func succ(){
29: savePassedByMD5(prePass.problem)
30: isSucc = true
31: UIAlertView(title: "祝贺你", message: "成功解决这个数独游戏题!", delegate: self, cancelButtonTitle: "确定").show()
32: }
33: // MARK: - 保存通过关卡的状态
34: func savePassedByMD5(pro:String){
35: var md5 = (pro as NSString).md5()
36: // NSUserDefaults.standardUserDefaults().
37: // println(NSUserDefaults.standardUserDefaults().boolForKey(md5))
38: NSUserDefaults.standardUserDefaults().setBool(true, forKey: md5)
39: NSUserDefaults.standardUserDefaults().synchronize()
40: // boolForKey(md5)
41:
42: }
43: // MARK: - 标记视图的相关操作
44: @IBOutlet weak var myMarkers: UIView!
45:
46: @IBAction func onTouchMarkerUnitCell(sender: UnitCell) {
47:
48: // println("onTouchMarkerPicker")
49: // println("\(sender.tag) curr=\(currentPickingUnitCell?.tag)")
50: currentPickingUnitCell?.addNumberMark(sender.tag)
51: disableMarkerPickerAndNumberPicker()
52: currentPickingUnitCell = nil
53:
54: }
55: func enableCancelButton(){
56: cancelButton.enabled = true
57: }
58: // MARK: - 数字选择视图的相关操作
59: @IBOutlet weak var myNumberPickerView: NumberPickerView!
60: @IBAction func onTouchNumberPicker(sender: UIButton) {
61: // println("touched number picker")
62: // println(" tag = \(sender.tag)")
63: if currentPickingUnitCell?.titleLabel?.text == "" {
64: // --remainCells
65: currentPickingUnitCell?.setCertainNumberBig(sender.tag)
66: disableMarkerPickerAndNumberPicker()
67: checkTotalAgain()
68: remainCellsCounter?.dec()
69: }else{
70: currentPickingUnitCell?.setCertainNumberBig(sender.tag)
71: disableMarkerPickerAndNumberPicker()
72: checkTotalAgain()
73: remainCellsCounter?.notChanged()
74: }
75: // checkNumberAvailable(sender.tag)
76:
77:
78: // println("remainCells\(remainCellsCounter?.count)")
79: }
80: // MARK: - 使标记视图和数字选择视图可以点击
81: func enableMarkerPickerAndNumberPicker(){
82: // cancelButton.enabled = true
83: cancelButton.hidden = false
84: currentPickingUnitCell?.backgroundColor = UIColor.blueColor()
85: for view in myMarkers.subviews as [UnitCell] {
86: view.enabled = true
87: }
88: myMarkers.hidden = false
89: for view in myNumberPickerView.subviews as [UIButton] {
90: view.enabled = true
91: }
92: myNumberPickerView.hidden = false
93: var (i,j) = getIJwithCertainUnitCell(currentPickingUnitCell!)
94: // println("i\(i) j\(j)")
95: // disableCorrespondingButtonWithIJ(i,jj: j)
96: //MARK TODO 参数标记需要优化
97: // makeUnavailableButtonWithIJ(i,jj: j)
98: }
99: // MARK: - 使标记视图和数字选择视图不可以点击
100: func disableMarkerPickerAndNumberPicker(){
101: cancelButton.enabled = false
102: cancelButton.hidden = true
103: currentPickingUnitCell?.backgroundColor = UIColor.whiteColor()
104: for view in myMarkers.subviews as [UnitCell] {
105: view.enabled = false
106: }
107: myMarkers.hidden = true
108: for view in myNumberPickerView.subviews as [UIButton] {
109: view.enabled = false
110: }
111: myNumberPickerView.hidden = true
112: currentPickingUnitCell = nil
113: }
114:
115: func checkTotalAgain(){
116: for i in 0...8 {
117: var t = 0
118: for j in 0...8 {
119: // println("i,j\(i),\(j) \(getTheUnitCell(i, j: j).titleLabel?.text)")
120: if getTheUnitCell(i, j: j).titleLabel!.text!.isEmpty {
121: continue
122: }
123: var k = getTheUnitCell(i, j: j).titleLabel!.text!.toInt()!;
124: var m = t&(1<<k)
125: if m != 0 {
126: notErr = false
127: return
128: }else{
129: t+=1<<k
130: }
131: }
132: }
133: for i in 0...8 {
134: var t = 0
135: for j in 0...8 {
136: if getTheUnitCell(j, j: i).titleLabel!.text!.isEmpty {
137: continue
138: }
139: var k = getTheUnitCell(j, j: i).titleLabel!.text!.toInt()!;
140: var m = t&(1<<k)
141: if m != 0 {
142: notErr = false
143: return
144: }else{
145: t+=1<<k
146: }
147: }
148: }
149: for a in 0...8 {
150: var t = 0
151: for b in 0...8 {
152: var ii = (a/3)*3+b/3
153: var jj = (a%3)*3 + b%3
154: if getTheUnitCell(ii, j: jj).titleLabel!.text!.isEmpty {
155: continue
156: }
157: var k = getTheUnitCell(ii, j: jj).titleLabel!.text!.toInt()!;
158: var m = t&(1<<k)
159: if m != 0 {
160: notErr = false
161: return
162: }else{
163: t+=1<<k
164: }
165: }
166: }
167: notErr = true
168:
169: }
170: // MARK: - (废弃)给定i,j坐标搜索无效的数字并禁止点按
171: func disableCorrespondingButtonWithIJ(ii:Int,jj:Int){
172: for i in 0...8 {
173: if i == ii {continue}
174: var unit = getTheUnitCell(i, j: jj);
175: if unit.titleLabel?.text != "" {
176: // println(unit.titleLabel?.text)
177: clearMarkerPickerAndNumberPickerWithNumber(unit.titleLabel!.text!.toInt()!)
178: }
179: }
180: for j in 0...8 {
181: if j == jj {continue}
182: var unit = getTheUnitCell(ii, j: j);
183: if unit.titleLabel?.text != "" {
184: clearMarkerPickerAndNumberPickerWithNumber(unit.titleLabel!.text!.toInt()!)
185: }
186: }
187: var si = ii/3*3
188: var sj = jj/3*3
189: for i in si...si+2 {
190: for j in sj...sj+2 {
191: if (i == ii)&&(j == jj) {continue}
192: var unit = getTheUnitCell(i, j: j);
193: if unit.titleLabel?.text != "" {
194: clearMarkerPickerAndNumberPickerWithNumber(unit.titleLabel!.text!.toInt()!)
195: }
196: }
197: }
198:
199: }
200: // MARK: - (废弃)使标记视图和数字选择视图的某些数字不可选择
201: func clearMarkerPickerAndNumberPickerWithNumber(i:Int){
202: // println("clear \(i)!!!")
203: for view in myMarkers.subviews as [UnitCell] {
204: // println(view.tag)
205: if view.tag == i {
206: view.enabled = false
207: // println("view enable \(view.enabled)")
208: break
209: }
210: }
211: for view in myNumberPickerView.subviews as [UIButton] {
212: // println(view.tag)
213: if view.tag == i {
214: view.enabled = false
215: // println("view enable \(view.enabled)")
216: break
217: }
218: }
219: }
220: // MARK: - 视图初始化相关操作
221: @IBOutlet weak var s99unit: SNNUnit!
222: @IBOutlet weak var cancelButton: UIButton!
223: override func viewDidLoad() {
224: super.viewDidLoad()
225: // println(prePass.problem)
226: initAllMyCells()
227: // initUnavailableNums()
228: remainCellsCounter = RemainCellsCounter(delegate1: self)
229: //TODO
230: // initArrays()
231: // initArrays
232: initArrays(prePass.problem)
233: // remainCellsCounter?.count = remainCells
234:
235:
236: }
237: // MARK: - 设置点击取消按钮时的操作
238: @IBAction func onTouchCancelButton(sender: UIButton) {
239: currentPickingUnitCell?.initCells()
240: // ++remainCells
241: remainCellsCounter?.inc()
242: disableMarkerPickerAndNumberPicker()
243: checkTotalAgain()
244: }
245:
246:
247:
248: // MARK: - 数组初始化
249:
250: func initArrays(withCertainInitials:Array <Array <Int>>){
251: for i in 0...8 {
252: for j in 0...8{
253: if withCertainInitials[i][j]==0 {
254: continue
255: }else{
256: lockUnitCell(i,j: j)
257: setUnitCellWithNumber(i,j: j,v: withCertainInitials[i][j])
258: }
259: }
260: }
261: }
262: func initArrays(withString:NSString){
263: for i in 0...8 {
264: for j in 0...8{
265: var t:String = withString.substringWithRange(NSMakeRange(i*9+j, 1))
266: var cnum = t.toInt()
267: if cnum == 0 {
268: continue
269: }else{
270: lockUnitCell(i,j: j)
271: setUnitCellWithNumber(i,j: j,v: cnum!)
272:
273: }
274: }
275: }
276: }
277:
278:
279: // MARK: - 单元格相关操作
280: @IBAction func onUnitCellTouch(sender: UnitCell) {
281: // println("touched remainCells\(remainCells)")
282: // println(" tag =\(sender.superview?.tag) \(sender.tag)")
283: if (sender == currentPickingUnitCell) {
284: // println("same!")
285: currentPickingUnitCell = nil
286: sender.backgroundColor = UIColor.whiteColor()
287: disableMarkerPickerAndNumberPicker()
288: return
289: }
290: if currentPickingUnitCell != nil {
291: currentPickingUnitCell?.backgroundColor = UIColor.whiteColor()
292: currentPickingUnitCell = nil
293: }
294:
295: currentPickingUnitCell = sender
296: // clearUnavailableNumber()//每次按下不同的单元格无效数字需清空
297: enableMarkerPickerAndNumberPicker()
298: if currentPickingUnitCell?.titleLabel?.text != "" {
299: enableCancelButton()
300: }
301:
302: }
303:
304: //UnitCell Ops
305: func getTheUnitCell(i:Int, j:Int)->UnitCell{
306: var a = (i/3)*3+j/3
307: var b = (i%3)*3+j%3
308: // println("(\(i),\(j))-> \(a), \(b)")
309: return s99unit.getTheUnitCell(
310: a
311: ,j: b
312: )
313:
314: }
315: func getIJwithCertainUnitCell(unit:UnitCell)->(i:Int,j:Int){
316: var b = unit.tag
317: var a = unit.superview!.tag % 10
318: // println("touch unit a\(a) b\(b)")
319: var ii = (a/3)*3+b/3
320: var jj = (a%3)*3 + b%3
321: return (ii,jj)
322:
323: }
324: func setUnitCellWithNumber(i:Int,j:Int,v:Int){
325: var unit = getTheUnitCell(i,j: j)
326: unit.setCertainNumberBig(v)
327: // --remainCells
328: remainCellsCounter?.dec()
329: }
330: func lockUnitCell(i:Int,j:Int){
331: var unit = getTheUnitCell(i,j: j)
332: unit.lockUnit()
333: }
334: func highlightUnitCell(cell:UnitCell,withColor:UIColor){
335: cell.backgroundColor = withColor
336: }
337: func initAllMyCells(){
338: s99unit.initAllCells()
339: for markerView in myMarkers.subviews as [UnitCell]{
340: markerView.layer.borderWidth=1
341: // markerView.setBackgroundImage(UIImage(named: "banBack"), forState: UIControlState.Disabled)
342: }
343: for numPickerView in myNumberPickerView.subviews as [UIButton]{
344: numPickerView.layer.borderWidth = 1
345: // numPickerView.setBackgroundImage(UIImage(named: "banBack"), forState: UIControlState.Disabled)
346: }
347:
348: disableMarkerPickerAndNumberPicker()
349:
350: }
351: // MARK: - 退出按钮操作
352: @IBAction func onExitTouched(sender: UIButton) {
353: // println("t")
354: // self.navigationController?.popToRootViewControllerAnimated(true)
355: // self.dismissViewControllerAnimated(true, completion:^{
356: //
357: // })
358: self.dismissViewControllerAnimated(true, completion: { () -> Void in
359: if self.isSucc {
360: NSNotificationCenter.defaultCenter().postNotificationName("reload", object: self)
361: }
362: })
363: }
364: // MARK: - 看答案按钮相关操作
365: @IBAction func onAnswerAsked(sender: AnyObject) {
366:
367: // var alert:UIAlertView!
368:
369: if prePass.solves.count>1 {
370: UIAlertView(title: "看答案", message: "确认看答案?", delegate: self, cancelButtonTitle: "取消",otherButtonTitles:"答案一","答案二").show()
371: }else{
372: UIAlertView(title: "看答案", message: "确认看答案?", delegate: self, cancelButtonTitle: "取消",otherButtonTitles:"答案一").show()
373:
374: }
375:
376:
377: }
378: var currentAns = 0
379: // MARK: alertview代理实现
380: func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int){
381: // println("touched \(alertView.title) \(buttonIndex) \(alertView.buttonTitleAtIndex(buttonIndex))")
382: if alertView.title == "看答案" {
383:
384: //
385: if alertView.buttonTitleAtIndex(buttonIndex) != "取消" {
386: currentAns = buttonIndex - 1
387: self.performSegueWithIdentifier("ans", sender: nil)
388:
389: }
390:
391: }
392: }
393:
394:
395: // MARK: 设置看答案时传递的参数
396: override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
397: if segue.identifier == "ans" {
398: var detailViewController:ShowAnswerController! = segue.destinationViewController as ShowAnswerController
399: // var index = self.tableView.indexPathForSelectedRow()
400: detailViewController.ans = prePass.solves[currentAns]
401: // detailViewController.cellTemp = (sender as UITableViewCell)
402:
403: }
404: }
405: override func didReceiveMemoryWarning() {
406: super.didReceiveMemoryWarning()
407: // Dispose of any resources that can be recreated.
408: }
409: // MARK: - 不用的代码以作备用
410: func junks(){
411: // override func targetViewControllerForAction(action: Selector, sender: AnyObject?) -> UIViewController? {
412: // return ShowAnswerController()
413: // }
414: //Initials
415: // func initArrays(){
416: // for i in 0...8
417: // {
418: // pickedNumberArray.append(Array(count:9,repeatedValue:0))
419: // }
420: // for i in 0...8
421: // {
422: // pickedMarkerArray.append(Array(count:9,repeatedValue:""))
423: // }
424: // }
425: /*
426: var boxLength = min(Int(self.view.frame.width)/5,Int(self.view.frame.height)/5)
427: println(boxLength)
428: var i=0,j=0
429: var marginY = (Int(self.view.frame.width) - boxLength*3)/4
430: var marginX = (Int(self.view.frame.height) - boxLength*3)/4
431: // for i in 0...8 {
432: // var sudokuView:UIView = UIView()
433: // sudokuView.backgroundColor = UIColor.redColor()
434: // sudokuView.frame = CGRectMake(
435: // margin*CGFloat(i-1)+CGFloat(boxLength*(i%3))
436: // ,margin*CGFloat(i-1)+CGFloat( boxLength*(i/3))
437: // , CGFloat(boxLength), CGFloat(boxLength))
438: //// sudokuView.
439: // self.view.addSubview(sudokuView)
440: // }
441:
442: for i in 0..<3 {
443: for j in 0..<3 {
444: var sudokuView:UIView = UIView()
<
请发表评论