-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeed.xml
1063 lines (825 loc) · 138 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.4.3">Jekyll</generator><link href="http://www.mycowsworld.com/feed.xml" rel="self" type="application/atom+xml" /><link href="http://www.mycowsworld.com/" rel="alternate" type="text/html" /><updated>2017-05-10T18:46:37-04:00</updated><id>http://www.mycowsworld.com/</id><title type="html">Mycow’s World</title><subtitle>Hi, I'm Michael Li. Welcome to my world.
</subtitle><entry><title type="html">Dominion (A Node.js Project)</title><link href="http://www.mycowsworld.com/blog/2017/04/26/dominion-nodejs.html" rel="alternate" type="text/html" title="Dominion (A Node.js Project)" /><published>2017-04-26T00:00:00-04:00</published><updated>2017-04-26T00:00:00-04:00</updated><id>http://www.mycowsworld.com/blog/2017/04/26/dominion-nodejs</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2017/04/26/dominion-nodejs.html"><p>A few years ago, my friends and I got really into the card game <a href="http://riograndegames.com/Game/278-Dominion">Dominion</a>. It’s a deck building game, but what made this game more enjoyable was the variation. In each round, you randomly select 10 cards that will be available for purchase, and the goal is to try to figure out different strategies for how those cards can interact with each other. The game is available on <a href="https://www.amazon.com/Rio-Grande-Games-RGG370-Dominion/dp/B001JQY6K4/ref=sr_1_2?s=toys-and-games&amp;ie=UTF8&amp;qid=1493409679&amp;sr=1-2&amp;keywords=dominion">Amazon</a> and is playable online via the official <a href="https://dominion.games">Dominion Online</a> site.</p>
<p>As a programming exercise, we attempted to create a similar game using Node.js. This post is to help me document the process we took to set up this project.</p>
<!-- more -->
<h2 id="step-1-install-nodejs">Step 1: Install Node.js</h2>
<p>Node.js is a runtime, or a program, that executes Javascript code on a server, thus allowing users to program server-side code using Javascript. For a good description of Node.js, check out this <a href="https://openclassrooms.com/courses/ultra-fast-applications-using-node-js/node-js-what-is-it-for-exactly">link</a>.</p>
<ul>
<li>Download and install <a href="https://nodejs.org/en/">Node.js</a>. The installer installs the Node.js and <a href="https://www.npmjs.com">npm</a>, a package manager for Javascript that allows you to quickly install libraries and other components.</li>
<li>Next, two libraries will be installed to help set up a server. <a href="http://expressjs.com">express</a> is used to easily instantiate the server, and <a href="https://socket.io">socket.io</a> is used for communication between server and client. To install, enter the following lines in a terminal</li>
</ul>
<figure class="highlight"><pre><code class="language-none" data-lang="none">$ npm install express
$ npm install socket.io</code></pre></figure>
<h2 id="step-2-set-up-server-code">Step 2: Set up Server Code</h2>
<p>Create a .js file for your server code (e.g. server.js). The following code sets up an initial server that runs on port 8081.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"express"</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">server</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"http"</span><span class="p">).</span><span class="nx">createServer</span><span class="p">(</span><span class="nx">app</span><span class="p">)</span>
<span class="kd">var</span> <span class="nx">io</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"socket.io"</span><span class="p">).</span><span class="nx">listen</span><span class="p">(</span><span class="nx">server</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"path"</span><span class="p">);</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="kr">static</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s2">"public"</span><span class="p">)));</span> <span class="c1">// Setting static folder to 'public' (relative to server.js)</span>
<span class="nx">server</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PORT</span> <span class="o">||</span> <span class="mi">8081</span><span class="p">);</span></code></pre></figure>
<p>For demonstration purposes, add a html file (index.html) to a folder named public. The file structure looks like this.</p>
<ul>
<li>my_dir/server.js</li>
<li>my_dir/public/index.html</li>
</ul>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="cp">&lt;!doctype html&gt;</span>
<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;h1&gt;</span>Hello World!<span class="nt">&lt;/h1&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span> </code></pre></figure>
<p>Then, start the server… (use Ctrl+C to stop the server)</p>
<figure class="highlight"><pre><code class="language-none" data-lang="none">$ node server.js</code></pre></figure>
<p>and access your file from your web browser with the following URL: <a href="http://127.0.0.1:8081">http://127.0.0.1:8081</a></p>
<h2 id="step-3-server-message-handling">Step 3: Server Message Handling</h2>
<p>Then, this code is used to set up message handling on the server side</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">io</span><span class="p">.</span><span class="nx">sockets</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"connection"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">socket</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// send a message to the client</span>
<span class="nx">io</span><span class="p">.</span><span class="nx">sockets</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s2">"&lt;message_name&gt;"</span><span class="p">,</span> <span class="o">&lt;</span><span class="nx">message_data</span><span class="o">&gt;</span><span class="p">);</span>
<span class="c1">// handler for message from client</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"&lt;message_name&gt;"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="o">&lt;</span><span class="nx">message_data</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do stuff here</span>
<span class="p">}</span>
<span class="c1">// add more handlers...</span>
<span class="p">}</span></code></pre></figure>
<h2 id="step-4-client-message-handling">Step 4: Client Message Handling</h2>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"/socket.io/socket.io.js"</span><span class="nt">&gt;&lt;/script&gt;</span></code></pre></figure>
<p>Add that to your client html page. This is served from your node server, which is available after installing socket.io.</p>
<p>In a corresponding client.js file, the following code can be used to handle client messaging.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">socket</span> <span class="o">=</span> <span class="nx">io</span><span class="p">.</span><span class="nx">connect</span><span class="p">();</span>
<span class="c1">// send a message to the server</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s2">"&lt;message_name&gt;"</span><span class="p">,</span> <span class="o">&lt;</span><span class="nx">message_data</span><span class="o">&gt;</span><span class="p">);</span>
<span class="c1">// handler for message from server</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"&lt;message_name&gt;"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="o">&lt;</span><span class="nx">message_data</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span></code></pre></figure>
<h2 id="step-5-serve-page">Step 5: Serve Page</h2>
<ul>
<li>Log in to your router</li>
<li>Find the Port Forwarding Options</li>
<li>Add a new Port Forwarding Rule… HOST DEVICE, HTTP (Web - Port 80), Forwarding to Port 8081</li>
<li>Find the Router’s IP Address (usually somewhere on the main router page)</li>
<li>Give out <Router IP="" Address="">:80 to others</Router></li>
</ul>
<h2 id="references">References</h2>
<h4 id="nodejs">Node.js</h4>
<ul>
<li><a href="https://openclassrooms.com/courses/ultra-fast-applications-using-node-js/node-js-what-is-it-for-exactly">https://openclassrooms.com/courses/ultra-fast-applications-using-node-js/node-js-what-is-it-for-exactly</a></li>
<li><a href="http://stackoverflow.com/questions/1884724/what-is-node-js">http://stackoverflow.com/questions/1884724/what-is-node-js</a></li>
<li><a href="http://www.programwitherik.com/getting-started-with-socket-io-node-js-and-express/">http://www.programwitherik.com/getting-started-with-socket-io-node-js-and-express/</a></li>
</ul></content><author><name></name></author><category term="Tutorial" /><category term="Javascript" /><category term="Node" /><summary type="html">A few years ago, my friends and I got really into the card game Dominion. It’s a deck building game, but what made this game more enjoyable was the variation. In each round, you randomly select 10 cards that will be available for purchase, and the goal is to try to figure out different strategies for how those cards can interact with each other. The game is available on Amazon and is playable online via the official Dominion Online site. As a programming exercise, we attempted to create a similar game using Node.js. This post is to help me document the process we took to set up this project.</summary></entry><entry><title type="html">Setting Up a GoDaddy Domain Name with GitHub</title><link href="http://www.mycowsworld.com/blog/2015/07/12/setting-up-a-godaddy-domain-name-with-github.html" rel="alternate" type="text/html" title="Setting Up a GoDaddy Domain Name with GitHub" /><published>2015-07-12T15:30:00-04:00</published><updated>2015-07-12T15:30:00-04:00</updated><id>http://www.mycowsworld.com/blog/2015/07/12/setting-up-a-godaddy-domain-name-with-github</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2015/07/12/setting-up-a-godaddy-domain-name-with-github.html"><p>I wanted to try using GitHub’s <a href="https://pages.github.com">Pages</a> feature to host my website. Turns out it was very simple to do, and the best part is it’s free!</p>
<p>Here’s a tutorial for setting up a GoDaddy domain name with this feature.</p>
<!-- more -->
<h2 id="step-1-register-for-a-domain-name">Step 1: Register for a domain name</h2>
<p>Go to <a href="http://www.godaddy.com/">http://www.godaddy.com/</a> and purchase a domain name (e.g. mycowsworld.com)</p>
<p>This reserves a name that people will use to access your website. Now you’ll need a place to store the files for your website.</p>
<h2 id="step-2-create-a-github-account">Step 2: Create a GitHub account</h2>
<p>Go to <a href="https://github.com">https://github.com</a> and sign up for an account.</p>
<h2 id="step-3-create-a-github-repository">Step 3: Create a GitHub repository</h2>
<p>Follow the instructions <a href="https://pages.github.com">here</a> (scroll down). This creates a repository where you will store your website files.</p>
<h2 id="step-4-link-your-domain-name-to-the-github-repository">Step 4: Link your domain name to the GitHub repository</h2>
<p>Follow the instructions <a href="https://help.github.com/articles/adding-or-removing-a-custom-domain-for-your-github-pages-site/">here</a> to connect your domain name (e.g. www.mycowsworld.com) to the GitHub repository.</p>
<h2 id="step-5-configure-dns-settings-on-godaddy">Step 5: Configure DNS settings on GoDaddy</h2>
<ol>
<li>Log in to GoDaddy.com</li>
<li>Click <strong>My Account</strong> at the top of the screen</li>
<li>In the <em>DOMAINS</em> pane, expand the section (click the + button) and click <strong>Manage</strong> for the desired domain name.</li>
<li>Under the <em>Settings</em> tab -&gt; Nameservers, click <strong>Manage</strong></li>
<li>Ensure that the <em>Setup Type</em> is set to <strong>Standard</strong> and save the changes. If you do make changes, note that it may take some time for the changes to propagate.</li>
<li>Under the <em>DNS Zone File</em> tab, click <strong>Add Record</strong></li>
<li>Select the <strong>CNAME</strong> Record Type</li>
<li>Under <em>Host</em>, enter in your <strong>www</strong></li>
<li>Under <em>Points to</em>, enter in the URL of the GitHub repository (e.g. username.github.io)</li>
<li>Click <strong>Finish</strong></li>
</ol>
<p>See <a href="https://help.github.com/articles/using-a-custom-domain-with-github-pages/">this page</a> for more information.</p>
<p>It will take some time for the changes to get pushed out, but once that happens, www.URL.com should take you to your GitHub page.</p>
<h2 id="step-6-redirect-urlcom-to-wwwurlcom">Step 6: Redirect URL.com to www.URL.com</h2>
<ol>
<li>Back in the GoDaddy page under the <em>Settings</em> tab -&gt; Forwarding, click <strong>Manage</strong> under <em>Domain</em>.</li>
<li>Click <strong>Add Domain Forwarding</strong></li>
<li>Under <em>Forward To</em>, set it to the desired webpage (e.g. http://www.mycowsworld.com)</li>
<li>Under <em>Redirect Type</em>, set it to <strong>301 Permanent</strong></li>
<li>Under <em>Forward Settings</em>, select <strong>Forward Only</strong></li>
<li>Check the <strong>Update my nameservers and DNS Settings to support this change</strong></li>
<li>Click <strong>Add</strong></li>
</ol>
<h2 id="references">References</h2>
<ul>
<li><a href="http://stackoverflow.com/questions/23097397/github-pages-setting-up-custom-domain">http://stackoverflow.com/questions/23097397/github-pages-setting-up-custom-domain</a></li>
<li><a href="https://help.github.com/articles/tips-for-configuring-a-cname-record-with-your-dns-provider/">https://help.github.com/articles/tips-for-configuring-a-cname-record-with-your-dns-provider/</a></li>
<li><a href="https://www.godaddy.com/help/managing-dns-for-your-domain-names-680">https://www.godaddy.com/help/managing-dns-for-your-domain-names-680</a></li>
<li><a href="https://pages.github.com">https://pages.github.com</a></li>
<li><a href="https://help.github.com/articles/adding-a-cname-file-to-your-repository/">https://help.github.com/articles/adding-a-cname-file-to-your-repository/</a></li>
</ul></content><author><name></name></author><category term="Tutorial" /><category term="Website" /><category term="Github" /><summary type="html">I wanted to try using GitHub’s Pages feature to host my website. Turns out it was very simple to do, and the best part is it’s free! Here’s a tutorial for setting up a GoDaddy domain name with this feature.</summary></entry><entry><title type="html">Boston Fishackathon 2015</title><link href="http://www.mycowsworld.com/blog/2015/07/12/boston-fishackathon-2015.html" rel="alternate" type="text/html" title="Boston Fishackathon 2015" /><published>2015-07-12T02:07:00-04:00</published><updated>2015-07-12T02:07:00-04:00</updated><id>http://www.mycowsworld.com/blog/2015/07/12/boston-fishackathon-2015</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2015/07/12/boston-fishackathon-2015.html"><p>I recently participated in the <a href="http://fishackathon.co">Boston Fishackathon</a>! Check out the project that my team created <a href="http://challengepost.com/software/yeah-buoii">here</a>.</p></content><author><name></name></author><category term="Code" /><category term="Hackathon" /><summary type="html">I recently participated in the Boston Fishackathon! Check out the project that my team created here.</summary></entry><entry><title type="html">Building a Computer</title><link href="http://www.mycowsworld.com/blog/2014/04/27/building-a-computer.html" rel="alternate" type="text/html" title="Building a Computer" /><published>2014-04-27T12:49:00-04:00</published><updated>2014-04-27T12:49:00-04:00</updated><id>http://www.mycowsworld.com/blog/2014/04/27/building-a-computer</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2014/04/27/building-a-computer.html"><p>Successfully built my first computer! For the list of parts, go to this link - <a href="http://pcpartpicker.com/p/2TYWa">PC Part Picker</a>. That website was extremely helpful. It checks your parts for compatibility issues, and you can see computer builds that other people have posted.</p>
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC1.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC1.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC1.jpg" />
-->
<!-- more -->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC2.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC2.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC2.jpg" />
-->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC3.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC3.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC3.jpg" />
-->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC4.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC4.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC4.jpg" />
-->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC5.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC5.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC5.jpg" />
-->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC6.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC6.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC6.jpg" />
-->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC7.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC7.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC7.jpg" />
-->
<div class="image-wrapper">
<a href="/assets/posts/2014-04-27-building-a-computer/LiPC8.jpg" title="">
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC8.jpg" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2014-04-27-building-a-computer/LiPC8.jpg" />
--></content><author><name></name></author><category term="Computer" /><category term="Photos" /><summary type="html">Successfully built my first computer! For the list of parts, go to this link - PC Part Picker. That website was extremely helpful. It checks your parts for compatibility issues, and you can see computer builds that other people have posted.</summary></entry><entry><title type="html">Paint (iOS)</title><link href="http://www.mycowsworld.com/blog/2013/12/31/paint-ios.html" rel="alternate" type="text/html" title="Paint (iOS)" /><published>2013-12-31T19:25:00-05:00</published><updated>2013-12-31T19:25:00-05:00</updated><id>http://www.mycowsworld.com/blog/2013/12/31/paint-ios</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2013/12/31/paint-ios.html"><p>In an effort to learn more iOS programming, I followed a tutorial to create a “Paint” program for iOS (<a href="http://www.raywenderlich.com/18840/how-to-make-a-simple-drawing-app-with-uikit">tutorial</a>).</p>
<div class="image-wrapper">
<a href="/assets/posts/2013-12-31-paint-ios/paint_main.png" title="">
<img src="/assets/posts/2013-12-31-paint-ios/paint_main.png" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2013-12-31-paint-ios/paint_main.png" />
-->
<p>For the source code, click <a href="https://github.com/moduli/Paint_iOS">here</a></p>
<!-- more -->
<h3 id="usage">Usage</h3>
<p>Clicking the Pencil icon allows the user to draw, and clicking the Eraser icon allows the user to erase existing lines.</p>
<p>In addition, there are several options on the top of the screen</p>
<ul>
<li>The <i>Reset</i> button clears everything on the screen</li>
<li>The <i>Save</i> button saves what’s on the screen to the your photos (camera roll)</li>
<li>The <i>Settings</i> button presents the user with options to change the size, transparency, and color of the brush.</li>
</ul></content><author><name></name></author><category term="Code" /><category term="iOS" /><category term="Objective-C" /><summary type="html">In an effort to learn more iOS programming, I followed a tutorial to create a “Paint” program for iOS (tutorial). For the source code, click here</summary></entry><entry><title type="html">Classic Battleships (iOS)</title><link href="http://www.mycowsworld.com/blog/2013/12/16/classic-battleships-ios.html" rel="alternate" type="text/html" title="Classic Battleships (iOS)" /><published>2013-12-16T23:34:00-05:00</published><updated>2013-12-16T23:34:00-05:00</updated><id>http://www.mycowsworld.com/blog/2013/12/16/classic-battleships-ios</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2013/12/16/classic-battleships-ios.html"><p>One of my class projects was to recreate the game “Classic Battleships” (see <a href="http://www.freeworldgroup.com/games9/gameindex/classicbattleships.htm">here</a> or <a href="http://www.conceptispuzzles.com/index.aspx?uri=puzzle/battleships">here</a> for an explanation of the rules) for iOS.</p>
<div class="image-wrapper">
<a href="/assets/posts/2013-12-16-classic-battleships-ios/battleship_game.png" title="">
<img src="/assets/posts/2013-12-16-classic-battleships-ios/battleship_game.png" alt="" />
</a>
</div>
<!--
<img src="/assets/posts/2013-12-16-classic-battleships-ios/battleship_game.png" />
-->
<p>For the source code, click <a href="https://github.com/moduli/Battleship_iOS">here</a>. Click through for more documentation.</p>
<!-- more -->
<h2 id="usage">Usage</h2>
<p>After launching the game, the user is met with three options…</p>
<ul>
<li>New Game - presents a list of levels that can be played. Selecting a level brings the user to the game screen</li>
<li>High Scores - presents a list of high scores for each level</li>
<li>Settings - presents options for the user to select</li>
</ul>
<p>In the game screen, the user can tap on a tile on the screen. The small black square is an empty tile, a blue square is a water tile, and a grey square is a ship tile. The numbers along the edges of the game screen represent the number of ship tiles in that row or column.</p>
<p>The other caveat is that the ship tiles must fall under a set number of configurations. For example, a level may require one 3x1 ship, two 2x1 ships, and three 1x1 ships. These ships can be in any orientation (horizontal or vertical). Note that ships cannot touch each other, meaning that a ship must be completely surrounded by water tiles.</p>
<h2 id="documentation">Documentation</h2>
<h3 id="breakpoints">Breakpoints</h3>
<p>To start off, I added a breakpoint for all exceptions. This would allow errors to be picked up at the point at which they were thrown instead of catching the exception once it propagates all the way up the stack.</p>
<ol>
<li>In the left panel, select the <b>Breakpoint Navigator</b></li>
<li>In the bottom left, click the ‘+’ sign</li>
<li>Click <b>Add Exception Breakpoint</b>.
<ul>
<li>A new breakpoint should appear in the Breakpoint Navigator list</li>
</ul>
</li>
<li>Right-click the new item, and click <b>Edit Breakpoint</b>. Ensure that <i>Exception</i> is set to <b>All</b> and <i>Break</i> is set to <b>On Throw</b></li>
</ol>
<h3 id="storyboard">Storyboard</h3>
<p>I first began by constructing the skeleton of the storyboard.</p>
<ol>
<li>In MainStoryboard.storyboard, drag a <b>Navigation Controller</b> object onto the storyboard.</li>
<li>By default, a <i>Table View Controller</i> is attached to the Navigation Controller. Delete the Table View Controller (Click -&gt; Delete) and drag a <b>View Controller</b> onto the storyboard.</li>
<li>To link the two together, right-click the Navigation Controller. Ctrl+click the circle in the <i>root view controller</i> row, and drag to the View Controller. This establishes the View Controller as the starting point.</li>
<li>Drag a <b>Table View Controller</b> object to the storyboard. This will be used for the level selection screen.</li>
<li>Drag a <b>Button</b> object onto the first View Controller.</li>
<li>Right-click the Button. Ctrl+click the circle in the <i>action</i> row, and drag to the Table View Controller.</li>
<li>In the resulting sub-menu, select Push.
<ul>
<li><i>Push</i> “pushes” the next screen on top of the current. one. This will present the user twith a Back button to move back to the current screen</li>
<li><i>Modal</i> presents another screen that isn’t “connected” to the current screen (like a pop-up)</li>
<li>This <a href="http://stackoverflow.com/questions/9392744/difference-between-modal-and-push-segue-in-storyboards">link</a> describes the differences fairly well</li>
</ul>
</li>
<li>Repeat this for other views</li>
</ol>
<h3 id="level-selection">Level Selection</h3>
<p>I then started to populate the Table View Controller. This View Controller is used to populate a list of available levels in the game.</p>
<ol>
<li>Add levels.txt to the project
<ol>
<li>File -&gt; Add Files to “Project”</li>
<li>Select levels.txt</li>
</ol>
</li>
<li>File -&gt; New -&gt; File -&gt; iOS/Cocoa Touch -&gt; <b>Objective-C Class</b></li>
<li>Set Class to <b>LevelSelectViewController</b></li>
<li>Set Subclass to <b>UITableViewController</b></li>
<li>Click <b>Next</b></li>
<li>Set Destination to your application’s directory</li>
<li>Click <b>Create</b></li>
<li>In the storyboard, select the Table View Controller</li>
<li>Select the <i>Identity</i> inspector in the right panel</li>
<li>In the <i>Custom class</i> section, set <i>Class</i> to <b>LevelSelectViewController</b>
<ol>
<li>This was the class created above. The option should be available in the drop-down menu</li>
<li>This tells this View Controller to use LevelSelectViewController</li>
</ol>
</li>
<li>Load the levels.txt file by adding the following code in LevelSelectViewController.m (viewDidLoad is invoked once the view controller has finished loading the view)</li>
</ol>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">viewDidLoad</span> <span class="p">{</span>
<span class="p">[</span><span class="n">super</span> <span class="nf">viewDidLoad</span><span class="p">];</span>
<span class="n">NSString</span><span class="o">*</span> <span class="n">file</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSBundle</span> <span class="nf">mainBundle</span><span class="p">]</span> <span class="nf">pathForResource</span><span class="p">:</span><span class="s">@"levels"</span> <span class="nf">ofType</span><span class="p">:</span><span class="s">@"txt"</span><span class="p">];</span>
<span class="n">NSString</span><span class="o">*</span> <span class="n">fileContents</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSString</span> <span class="nf">stringWithContentsOfFile</span><span class="p">:</span><span class="n">file</span> <span class="nf">encoding</span><span class="p">:</span><span class="n">NSUTF8StringEncoding</span> <span class="n">error</span><span class="o">:</span><span class="nb">nil</span><span class="p">];</span>
<span class="n">NSArray</span><span class="o">*</span> <span class="n">allLines</span> <span class="o">=</span> <span class="p">[</span><span class="n">fileContents</span> <span class="nf">componentsSeparatedByCharactersInSet</span><span class="p">:[</span><span class="n">NSCharacterSet</span> <span class="nf">newlineCharacterSet</span><span class="p">]];</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="p">[</span><span class="n">allLines</span> <span class="nf">count</span><span class="p">];</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// process text file...
</span> <span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>In MainStoryboard.storyboard, select the Prototype Cell (the lone entry in the table) in the LevelSelectViewController object. In the Identity inspector, set <i>Restoration ID</i> to some name (I picked <b>LevelCell</b>)</p>
<p>In LevelSelectViewController.m, implement the associated UITableViewController functions (since this class subclassed UITableViewController, the associated functions were already added to the .m file)</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="k">-</span> <span class="p">(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nf">numberOfSectionsInTableView</span><span class="p">:(</span><span class="n">UITableView</span> <span class="o">*</span><span class="p">)</span><span class="nv">tableView</span> <span class="p">{</span>
<span class="c1">// Return the number of sections
</span> <span class="c1">// we only have one section/group in table
</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">-</span> <span class="p">(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nf">tableView</span><span class="p">:(</span><span class="n">UITableView</span> <span class="o">*</span><span class="p">)</span><span class="nv">tableView</span> <span class="nf">numberOfRowsInSection</span><span class="p">:(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nv">section</span> <span class="p">{</span>
<span class="c1">// Return the number of rows in the section.
</span> <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">levels</span><span class="p">.</span><span class="n">count</span><span class="p">;</span> <span class="c1">// I stored all of the levels in an array
</span><span class="p">}</span>
<span class="k">-</span> <span class="p">(</span><span class="n">UITableViewCell</span> <span class="o">*</span><span class="p">)</span><span class="nf">tableView</span><span class="p">:(</span><span class="n">UITableView</span> <span class="o">*</span><span class="p">)</span><span class="nv">tableView</span> <span class="nf">cellForRowAtIndexPath</span><span class="p">:(</span><span class="n">NSIndexPath</span> <span class="o">*</span><span class="p">)</span><span class="nv">indexPath</span> <span class="p">{</span>
<span class="c1">// this function will be called for each row in the table
</span>
<span class="c1">// populate table
</span> <span class="n">Level</span><span class="o">*</span> <span class="n">level</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">levels</span> <span class="nf">objectAtIndex</span><span class="p">:</span><span class="n">indexPath</span><span class="p">.</span><span class="n">row</span><span class="p">];</span>
<span class="k">static</span> <span class="n">NSString</span><span class="o">*</span> <span class="n">CellIdentifier</span> <span class="o">=</span> <span class="s">@"LevelCell"</span><span class="p">;</span> <span class="c1">// defined in StoryBoard (CustomCollectionView)
</span> <span class="n">UITableViewCell</span><span class="o">*</span> <span class="n">cell</span> <span class="o">=</span> <span class="p">[</span><span class="n">tableView</span> <span class="nf">dequeueReusableCellWithIdentifier</span><span class="p">:</span><span class="n">CellIdentifier</span> <span class="nf">forIndexPath</span><span class="p">:</span><span class="n">indexPath</span><span class="p">];</span>
<span class="c1">// set cell label
</span> <span class="n">cell</span><span class="p">.</span><span class="n">textLabel</span><span class="p">.</span><span class="n">text</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSString</span> <span class="nf">stringWithFormat</span><span class="p">:</span><span class="s">@"Board%@ (%dx%d)"</span><span class="p">,</span><span class="n">level</span><span class="p">.</span><span class="n">board_id</span><span class="p">,</span><span class="n">level</span><span class="p">.</span><span class="n">board_size</span><span class="p">,</span><span class="n">level</span><span class="p">.</span><span class="n">board_size</span><span class="p">];</span>
<span class="k">return</span> <span class="n">cell</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<h3 id="game-screen">Game Screen</h3>
<h4 id="storyboard-1">Storyboard</h4>
<p>To create the game board…</p>
<ol>
<li>Drag a Collection View object to a new view controller.</li>
<li>Click the prototype cell in the Collection View (the first tile), and set an Identifier in the Attributes inspector (similar to the Level Select screen). In this case, I named it <b>GameTileCell</b></li>
<li>Create a custom class for the Collection View
<ol>
<li>File -&gt; New -&gt; File -&gt; iOS/Cocoa Touch -&gt; Objective-C Class</li>
<li>Set <i>Class</i> to <b>CustomCollectionView</b></li>
<li>Set <i>Subclass</i> to <b>UICollectionView</b></li>
<li>Click <b>Next</b></li>
<li>Set destination to your application’s directory</li>
<li>Click <b>Create</b></li>
</ol>
</li>
<li>Click the Collection View object, navigate to the <i>Identity</i> inspector, and set the <i>Custom Class</i> to <b>CustomCollectionView</b></li>
</ol>
<h4 id="code">Code</h4>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="cp">#pragma mark - UICollectionViewDataSource
</span><span class="k">-</span> <span class="p">(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nf">numberOfSectionsInCollectionView</span><span class="p">:(</span><span class="n">UICollectionView</span> <span class="o">*</span><span class="p">)</span><span class="nv">collectionView</span> <span class="p">{</span>
<span class="c1">// Returns the total number of sections
</span> <span class="c1">// only one section
</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">-</span> <span class="p">(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nf">collectionView</span><span class="p">:(</span><span class="n">UICollectionView</span> <span class="o">*</span><span class="p">)</span><span class="nv">view</span> <span class="nf">numberOfItemsInSection</span><span class="p">:(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nv">section</span> <span class="p">{</span>
<span class="c1">// Returns the number of cells to be displayed for a given section
</span> <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">tiles_count</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">-</span> <span class="p">(</span><span class="n">UICollectionViewCell</span> <span class="o">*</span><span class="p">)</span><span class="nf">collectionView</span><span class="p">:(</span><span class="n">UICollectionView</span> <span class="o">*</span><span class="p">)</span><span class="nv">cv</span> <span class="nf">cellForItemAtIndexPath</span><span class="p">:(</span><span class="n">NSIndexPath</span> <span class="o">*</span><span class="p">)</span><span class="nv">indexPath</span> <span class="p">{</span>
<span class="c1">// Returns the cell at a given index
</span> <span class="c1">// cells with tag 0: informational tile
</span> <span class="c1">// cells with tag 1: game tile
</span> <span class="c1">//NSLog(@"FOR %d", indexPath.item);
</span>
<span class="c1">// obtain a cell of ID "GameTileCell" (either new cell or one that can be reused)
</span> <span class="n">GameTile</span><span class="o">*</span> <span class="n">cell</span> <span class="o">=</span> <span class="p">[</span><span class="n">cv</span> <span class="nf">dequeueReusableCellWithReuseIdentifier</span><span class="p">:</span><span class="s">@"GameTileCell"</span> <span class="nf">forIndexPath</span><span class="p">:</span><span class="n">indexPath</span><span class="p">];</span>
<span class="c1">// set cell parameters...
</span>
<span class="c1">//NSLog(@"FOR %d, %d", cell.row, cell.column);
</span> <span class="k">return</span> <span class="n">cell</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">#pragma mark - UICollectionViewDelegateFlowLayout
</span><span class="c1">// Specify size of a cell
</span><span class="k">-</span> <span class="p">(</span><span class="n">CGSize</span><span class="p">)</span><span class="nf">collectionView</span><span class="p">:(</span><span class="n">UICollectionView</span> <span class="o">*</span><span class="p">)</span><span class="nv">collectionView</span> <span class="nf">layout</span><span class="p">:(</span><span class="n">UICollectionViewLayout</span><span class="o">*</span><span class="p">)</span><span class="nv">collectionViewLayout</span> <span class="nf">sizeForItemAtIndexPath</span><span class="p">:(</span><span class="n">NSIndexPath</span> <span class="o">*</span><span class="p">)</span><span class="nv">indexPath</span> <span class="p">{</span>
<span class="n">NSInteger</span> <span class="n">row</span> <span class="o">=</span> <span class="n">indexPath</span><span class="p">.</span><span class="n">item</span> <span class="o">/</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">brain</span><span class="p">.</span><span class="n">board_size</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="n">NSInteger</span> <span class="n">column</span> <span class="o">=</span> <span class="n">indexPath</span><span class="p">.</span><span class="n">item</span> <span class="o">%</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">brain</span><span class="p">.</span><span class="n">board_size</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="c1">// calculate size of cell based on collectionview size
</span> <span class="n">CGRect</span> <span class="n">frame</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">board_layout</span> <span class="nf">frame</span><span class="p">];</span>
<span class="n">NSInteger</span> <span class="n">cellsize</span> <span class="o">=</span> <span class="p">(</span><span class="n">frame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">brain</span><span class="p">.</span><span class="n">board_size</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="n">CGSize</span> <span class="n">retval</span> <span class="o">=</span> <span class="n">CGSizeMake</span><span class="p">(</span><span class="n">cellsize</span><span class="p">,</span> <span class="n">cellsize</span><span class="p">);</span>
<span class="c1">//NSLog(@"ROW: %d, COL: %d, SIZE X: %f, SIZE Y: %f",row, column, retval.width, retval.height);
</span> <span class="c1">//NSLog(@"WIDTH: %f HEIGHT: %f", frame.size.width, frame.size.height);
</span> <span class="k">return</span> <span class="n">retval</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Returns spacing between cells, headers, and footers
</span><span class="k">-</span> <span class="p">(</span><span class="n">UIEdgeInsets</span><span class="p">)</span><span class="nf">collectionView</span><span class="p">:</span>
<span class="p">(</span><span class="n">UICollectionView</span><span class="o">*</span><span class="p">)</span><span class="nv">collectionView</span> <span class="nf">layout</span><span class="p">:(</span><span class="n">UICollectionViewLayout</span><span class="o">*</span><span class="p">)</span><span class="nv">collectionViewLayout</span> <span class="nf">insetForSectionAtIndex</span><span class="p">:(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nv">section</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">UIEdgeInsetsMake</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<h3 id="high-scores">High Scores</h3>
<p>I ended up using SQLite for storing high scores (an alternative would be to use Core Data, but I didn’t investigate that path enough).</p>
<p>Add the following code to load the SQL database (or create one if the database cannot be found). For my project, this code was added to the application didFinishLaunchingWithOptions function in BattleshipAppDelegate.m</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="n">NSArray</span><span class="o">*</span> <span class="n">dirPaths</span> <span class="o">=</span> <span class="n">NSSearchPathForDirectoriesInDomains</span><span class="p">(</span><span class="n">NSDocumentDirectory</span><span class="p">,</span> <span class="n">NSUserDomainMask</span><span class="p">,</span> <span class="nb">YES</span><span class="p">);</span> <span class="c1">// get a list of directories that are owned by the application
</span><span class="n">NSString</span><span class="o">*</span> <span class="n">docsDir</span> <span class="o">=</span> <span class="n">dirPaths</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="c1">// assume it's in the first directory
</span><span class="n">self</span><span class="p">.</span><span class="n">databasePath</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSString</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">initWithString</span><span class="p">:[</span><span class="n">docsDir</span> <span class="nf">stringByAppendingPathComponent</span><span class="p">:</span><span class="s">@"scores.db"</span><span class="p">]];</span> <span class="c1">// this is the expected path to where the database should live ('docsDir . "/scores.db/')
</span><span class="n">NSFileManager</span> <span class="o">*</span><span class="n">filemgr</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSFileManager</span> <span class="nf">defaultManager</span><span class="p">];</span> <span class="c1">// define filemanager. this is used to look up if a file exists or not
</span>
<span class="c1">// if database file doesn't exist, create it
</span><span class="k">if</span> <span class="p">([</span><span class="n">filemgr</span> <span class="nf">fileExistsAtPath</span><span class="p">:</span><span class="n">self</span><span class="p">.</span><span class="n">databasePath</span><span class="p">]</span> <span class="o">==</span> <span class="nb">NO</span><span class="p">)</span> <span class="p">{</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">dbPath</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">databasePath</span> <span class="nf">UTF8String</span><span class="p">];</span> <span class="c1">// convert pathname to UTF8 String
</span> <span class="n">sqlite3</span><span class="o">*</span> <span class="n">scoresDB</span><span class="p">;</span> <span class="c1">// stores pointer to high scores database
</span>
<span class="c1">// create a database at the specified path
</span> <span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_open</span><span class="p">(</span><span class="n">dbPath</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">scoresDB</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_OK</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">errorMsg</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">sql_stmt</span> <span class="o">=</span> <span class="s">"CREATE TABLE IF NOT EXISTS SCORES (ID INTEGER PRIMARY KEY AUTOINCREMENT, BOARD INTEGER, MINUTES INTEGER, SECONDS INTEGER, RANK INTEGER);"</span><span class="p">;</span>
<span class="c1">// create table in database
</span> <span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_exec</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">,</span> <span class="n">sql_stmt</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">errorMsg</span><span class="p">)</span> <span class="o">!=</span> <span class="n">SQLITE_OK</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//NSLog(@"Failed to create table");
</span> <span class="p">}</span>
<span class="n">sqlite3_close</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">NSLog</span><span class="p">(</span><span class="s">@"Failed to open/create database"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">//</span> <span class="n">self</span><span class="p">.</span><span class="n">databasePath</span> <span class="n">will</span> <span class="n">be</span> <span class="n">used</span></code></pre></figure>
<p>Here’s an example of using a SELECT statement. This was used in the High Scores View Controller to retrieve a list of levels that contained high scores.</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="n">BattleshipAppDelegate</span><span class="o">*</span> <span class="n">delegate</span> <span class="o">=</span> <span class="p">(</span><span class="n">BattleshipAppDelegate</span><span class="o">*</span><span class="p">)</span> <span class="p">[[</span><span class="n">UIApplication</span> <span class="nf">sharedApplication</span><span class="p">]</span> <span class="nf">delegate</span><span class="p">];</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">dbPath</span> <span class="o">=</span> <span class="p">[</span><span class="n">delegate</span><span class="p">.</span><span class="n">databasePath</span> <span class="nf">UTF8String</span><span class="p">];</span> <span class="c1">// determined above
</span><span class="n">sqlite3</span><span class="o">*</span> <span class="n">scoresDB</span><span class="p">;</span>
<span class="c1">// open the database
</span><span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_open</span><span class="p">(</span><span class="n">dbPath</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">scoresDB</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_OK</span><span class="p">)</span> <span class="p">{</span>
<span class="n">NSString</span><span class="o">*</span> <span class="n">query</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSString</span> <span class="nf">stringWithFormat</span><span class="p">:</span><span class="s">@"SELECT DISTINCT BOARD FROM SCORES ORDER BY ID ASC"</span><span class="p">];</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">query_stmt</span> <span class="o">=</span> <span class="p">[</span><span class="n">query</span> <span class="nf">UTF8String</span><span class="p">];</span>
<span class="c1">// query database for all unique boards
</span> <span class="n">sqlite3_stmt</span><span class="o">*</span> <span class="n">statement</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_prepare_v2</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">,</span> <span class="n">query_stmt</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">statement</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_OK</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// if at least one row returns
</span> <span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_step</span><span class="p">(</span><span class="n">statement</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_ROW</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// step through each returned row of data
</span> <span class="k">do</span> <span class="p">{</span>
<span class="n">NSNumber</span><span class="o">*</span> <span class="n">board_id</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSNumber</span> <span class="nf">numberWithInt</span><span class="p">:</span><span class="n">sqlite3_column_int</span><span class="p">(</span><span class="n">statement</span><span class="p">,</span> <span class="mi">0</span><span class="p">)];</span>
<span class="c1">//NSLog(@"BOARD ID: %@", board_id);
</span>
<span class="p">[</span><span class="n">boards</span> <span class="nf">addObject</span><span class="p">:</span><span class="n">board_id</span><span class="p">];</span>
<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">sqlite3_step</span><span class="p">(</span><span class="n">statement</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_ROW</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">sqlite3_finalize</span><span class="p">(</span><span class="n">statement</span><span class="p">);</span> <span class="c1">// release compiled statement from memory
</span> <span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">NSLog</span><span class="p">(</span><span class="s">@"Failed SQL PREPARE. Error is: %s"</span><span class="p">,</span> <span class="n">sqlite3_errmsg</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">));</span>
<span class="p">}</span>
<span class="c1">// close database connection
</span> <span class="n">sqlite3_close</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>Here’s an example of using a DELETE statement. This was used in the Settings View Controller to delete all the high scores from the database.</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="n">BattleshipAppDelegate</span><span class="o">*</span> <span class="n">delegate</span> <span class="o">=</span> <span class="p">(</span><span class="n">BattleshipAppDelegate</span><span class="o">*</span><span class="p">)</span> <span class="p">[[</span><span class="n">UIApplication</span> <span class="nf">sharedApplication</span><span class="p">]</span> <span class="nf">delegate</span><span class="p">];</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">dbPath</span> <span class="o">=</span> <span class="p">[</span><span class="n">delegate</span><span class="p">.</span><span class="n">databasePath</span> <span class="nf">UTF8String</span><span class="p">];</span>
<span class="n">sqlite3</span><span class="o">*</span> <span class="n">scoresDB</span><span class="p">;</span>
<span class="c1">// open high scores database
</span><span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_open</span><span class="p">(</span><span class="n">dbPath</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">scoresDB</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_OK</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// generate command to delete all entries in database
</span> <span class="n">NSString</span><span class="o">*</span> <span class="n">query</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSString</span> <span class="nf">stringWithFormat</span><span class="p">:</span><span class="s">@"DELETE FROM SCORES"</span><span class="p">];</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">delete_stmt</span> <span class="o">=</span> <span class="p">[</span><span class="n">query</span> <span class="nf">UTF8String</span><span class="p">];</span>
<span class="n">sqlite3_stmt</span><span class="o">*</span> <span class="n">statement</span><span class="p">;</span>
<span class="c1">// execute command
</span> <span class="n">sqlite3_prepare_v2</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">,</span> <span class="n">delete_stmt</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">statement</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="c1">// check results of execution
</span> <span class="k">if</span> <span class="p">(</span><span class="n">sqlite3_step</span><span class="p">(</span><span class="n">statement</span><span class="p">)</span> <span class="o">==</span> <span class="n">SQLITE_DONE</span><span class="p">)</span> <span class="p">{</span>
<span class="n">NSLog</span><span class="p">(</span><span class="s">@"Deleted"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">NSLog</span><span class="p">(</span><span class="s">@"Error: Deleting Score"</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// release compiled statement from memory
</span> <span class="n">sqlite3_finalize</span><span class="p">(</span><span class="n">statement</span><span class="p">);</span>
<span class="c1">// close database connection
</span> <span class="n">sqlite3_close</span><span class="p">(</span><span class="n">scoresDB</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<h3 id="settings">Settings</h3>
<h4 id="storyboard-2">Storyboard</h4>
<ol>
<li>Drag a new <b>Table View Controller</b> into the storyboard</li>
<li>Select the view controller and navigate to the <i>Attributes</i> inspector</li>
<li>Set <i>Content</i> to <b>Static Cells</b>.
<ol>
<li>This means you will define how the cells look in storyboard rather than dynamically through code (like we did in the Level Select View Controller)</li>
</ol>
</li>
<li>Set <i>Sections</i> to how many logical groups of settings you want. In this case, I picked <b>2</b>.</li>
<li>You can add/remove cells from each group as you see fit. If you want to add more, drag a Table View Cell object into a particular group.</li>
<li>To customize a cell, drag objects (e.g. labels, switches) onto each cell.</li>
<li>By default, each cell is selectable (like a button). I left this behavior on the <i>Reset High Scores</i> option. However, I did not want this behavior on the Sound toggle option. Highlight the corresponding cell, navigate to the <i>Attributes</i> inspector, and set <i>Selection</i> to <b>None</b>.</li>
</ol>
<h4 id="code-1">Code</h4>
<ol>
<li>File -&gt; New -&gt; File -&gt; iOS/Resource -&gt; <b>Property List</b></li>
<li>Save As <b>defaults</b></li>
<li>Click <b>Create</b></li>
<li>Select <b>defaults.plist</b> in <i>Project Navigator</i></li>
<li>Right-click <b>Root</b></li>
<li>Click <b>Add Row</b></li>
<li>Name the property (e.g. <b>soundEnabled</b>)</li>
<li>Set the property type (e.g. <b>Boolean</b>)</li>
<li>Set the default value (e.g. <b>YES</b>)</li>
<li>In BattleshipAppDelegate.m, add the following statement to load the defaults.plist file once the application has finished loading.</li>
</ol>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="k">-</span> <span class="p">(</span><span class="n">BOOL</span><span class="p">)</span><span class="nf">application</span><span class="p">:(</span><span class="n">UIApplication</span> <span class="o">*</span><span class="p">)</span><span class="nv">application</span> <span class="nf">didFinishLaunchingWithOptions</span><span class="p">:(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">launchOptions</span> <span class="p">{</span>
<span class="c1">//...
</span> <span class="p">[[</span><span class="n">NSUserDefaults</span> <span class="nf">standardUserDefaults</span><span class="p">]</span> <span class="nf">registerDefaults</span><span class="p">:[</span><span class="n">NSDictionary</span> <span class="nf">dictionaryWithContentsOfFile</span><span class="p">:[[</span><span class="n">NSBundle</span> <span class="nf">mainBundle</span><span class="p">]</span> <span class="nf">pathForResource</span><span class="p">:</span><span class="s">@"defaults"</span> <span class="nf">ofType</span><span class="p">:</span><span class="s">@"plist"</span><span class="p">]]];</span>
<span class="c1">//...
</span><span class="p">}</span></code></pre></figure>
<p>To access these values…</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="n">NSUserDefaults</span><span class="o">*</span> <span class="n">settings</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSUserDefaults</span> <span class="nf">standardUserDefaults</span><span class="p">];</span>
<span class="n">BOOL</span> <span class="n">soundEnabled</span> <span class="o">=</span> <span class="p">[</span><span class="n">settings</span> <span class="nf">boolForKey</span><span class="p">:</span><span class="s">@"soundEnabled"</span><span class="p">];</span></code></pre></figure>
<p>To change a value…</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="n">NSUserDefaults</span><span class="o">*</span> <span class="n">settings</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSUserDefaults</span> <span class="nf">standardUserDefaults</span><span class="p">];</span>
<span class="p">[</span><span class="n">settings</span> <span class="nf">setBool</span><span class="p">:</span><span class="nb">true</span> <span class="nf">forKey</span><span class="p">:</span><span class="s">@"soundEnabled"</span><span class="p">];</span></code></pre></figure>
<h3 id="alerts">Alerts</h3>
<p>Alerts (pop-ups) were added to the game to confirm that a user wanted to proceed with a certain action. This was used in two places. The first was to confirm that a user wanted to reset all of the stored high scores. The second was to confirm that a user wanted to reset his/her progress on a current level.</p>
<p>To present the user with an alert, the following code was invoked after a user tapped a button</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">showAlert</span> <span class="p">{</span>
<span class="n">UIAlertView</span><span class="o">*</span> <span class="n">alert</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIAlertView</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">initWithTitle</span><span class="p">:</span><span class="s">@"Reset High Score?"</span>
<span class="nf">message</span><span class="p">:</span><span class="s">@"Are you sure you want to reset high scores?"</span>
<span class="n">delegate</span><span class="o">:</span><span class="n">self</span> <span class="c1">// delegate set to self =&gt; this view controller will get a callback - need to implement the callback (see alertView didDismissWithButtonIndex)
</span> <span class="nl">cancelButtonTitle:</span><span class="s">@"Cancel"</span>
<span class="n">otherButtonTitles</span><span class="o">:</span><span class="s">@"Yes"</span><span class="p">,</span><span class="nb">nil</span><span class="p">];</span> <span class="c1">// could add more buttons after "Yes". List of buttons ends in "nil".
</span> <span class="p">[</span><span class="n">alert</span> <span class="nf">setTag</span><span class="p">:</span><span class="mi">1</span><span class="p">];</span> <span class="c1">// alert ID
</span> <span class="p">[</span><span class="n">alert</span> <span class="nf">show</span><span class="p">];</span>
<span class="p">}</span></code></pre></figure>
<p>To react to the user’s response to the pop-up, the following function was added</p>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">alertView</span><span class="p">:(</span><span class="n">UIAlertView</span><span class="o">*</span><span class="p">)</span><span class="nv">alertView</span> <span class="nf">didDismissWithButtonIndex</span><span class="p">:(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nv">buttonIndex</span> <span class="p">{</span>
<span class="c1">// tag set above
</span> <span class="k">if</span> <span class="p">(</span><span class="n">alertView</span><span class="p">.</span><span class="n">tag</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// cancel
</span> <span class="k">if</span> <span class="p">(</span><span class="n">buttonIndex</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="c1">// OK
</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">buttonIndex</span> <span class="o">!=</span> <span class="n">alertView</span><span class="p">.</span><span class="n">cancelButtonIndex</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do something
</span> <span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<h3 id="sounds">Sounds</h3>
<p>To add sounds to the game…</p>
<ol>
<li>File -&gt; Add Files to “Project”</li>
<li>Select an mp3 file (in this case, I added ff6_victory.mp3)</li>
<li>Add the following code…</li>
</ol>
<figure class="highlight"><pre><code class="language-objective_c" data-lang="objective_c"><span class="c1">// load sounds
</span><span class="n">NSString</span><span class="o">*</span> <span class="n">soundPath</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSBundle</span> <span class="nf">mainBundle</span><span class="p">]</span> <span class="nf">pathForResource</span><span class="p">:</span><span class="s">@"ff6_victory"</span> <span class="nf">ofType</span><span class="p">:</span><span class="s">@"mp3"</span><span class="p">];</span>
<span class="n">NSURL</span><span class="o">*</span> <span class="n">filePath</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSURL</span> <span class="nf">fileURLWithPath</span><span class="p">:</span><span class="n">soundPath</span> <span class="nf">isDirectory</span><span class="p">:</span><span class="nb">false</span><span class="p">];</span>
<span class="n">AVAudioPlayer</span><span class="o">*</span> <span class="n">audioplayer</span> <span class="o">=</span> <span class="p">[[</span><span class="n">AVAudioPlayer</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">initWithContentsOfURL</span><span class="p">:</span><span class="n">filePath</span> <span class="nf">error</span><span class="p">:</span><span class="nb">nil</span><span class="p">];</span>
<span class="p">[</span><span class="n">audioplayer</span> <span class="nf">prepareToPlay</span><span class="p">];</span>
<span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">soundplayers</span> <span class="nf">addObject</span><span class="p">:</span><span class="n">audioplayer</span><span class="p">];</span> <span class="c1">// all my sounds were added to this array
</span>
<span class="c1">// play sound
</span><span class="n">audioplayer</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">soundplayers</span> <span class="nf">objectAtIndex</span><span class="p">:</span><span class="mi">0</span><span class="p">];</span>
<span class="p">[</span><span class="n">audioplayer</span> <span class="nf">play</span><span class="p">];</span>
<span class="c1">// stop sound
</span><span class="n">audioplayer</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">soundplayers</span> <span class="nf">objectAtIndex</span><span class="p">:</span><span class="mi">0</span><span class="p">];</span>
<span class="p">[</span><span class="n">audioplayer</span> <span class="nf">stop</span><span class="p">];</span></code></pre></figure>
<h2 id="references">References</h2>
<h3 id="storyboards">Storyboards</h3>
<ul>
<li><a href="http://www.techotopia.com/index.php/Using_Xcode_Storyboarding_(iPhone_iOS_5)">http://www.techotopia.com/index.php/Using_Xcode_Storyboarding_(iPhone_iOS_5)</a></li>
<li><a href="http://kurrytran.blogspot.com/2011/07/simple-ios-5-tutorial-using-storyboard.html">http://kurrytran.blogspot.com/2011/07/simple-ios-5-tutorial-using-storyboard.html</a></li>
</ul>
<h3 id="uicollectionview">UICollectionView</h3>
<ul>
<li><a href="http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12">http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12</a></li>
<li><a href="http://skeuo.com/uicollectionview-custom-layout-tutorial">http://skeuo.com/uicollectionview-custom-layout-tutorial</a></li>
<li><a href="http://www.appcoda.com/ios-programming-uicollectionview-tutorial/">http://www.appcoda.com/ios-programming-uicollectionview-tutorial/</a></li>
</ul>
<h3 id="passing-data-between-view-controllers">Passing Data Between View Controllers</h3>
<ul>
<li><a href="http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers">http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers</a></li>
</ul>
<h3 id="reading-a-text-file">Reading a Text File</h3>
<ul>
<li><a href="http://stackoverflow.com/questions/7828073/reading-a-text-file-in-objective-c">http://stackoverflow.com/questions/7828073/reading-a-text-file-in-objective-c</a></li>
</ul>
<h3 id="nsuserdefaults">NSUserDefaults</h3>
<ul>
<li><a href="http://stackoverflow.com/questions/2076816/how-to-register-user-defaults-using-nsuserdefaults-without-overwriting-existing">http://stackoverflow.com/questions/2076816/how-to-register-user-defaults-using-nsuserdefaults-without-overwriting-existing</a></li>
<li><a href="http://stackoverflow.com/questions/9927094/ios-saving-high-score-locally">http://stackoverflow.com/questions/9927094/ios-saving-high-score-locally</a></li>
</ul>
<h3 id="sqlite">SQLite</h3>
<ul>
<li><a href="http://www.techotopia.com/index.php/An_Example_SQLite_based_iOS_6_iPhone_Application">http://www.techotopia.com/index.php/An_Example_SQLite_based_iOS_6_iPhone_Application</a></li>
</ul></content><author><name></name></author><category term="Code" /><category term="iOS" /><category term="Objective-C" /><summary type="html">One of my class projects was to recreate the game “Classic Battleships” (see here or here for an explanation of the rules) for iOS. For the source code, click here. Click through for more documentation.</summary></entry><entry><title type="html">Sublime Text</title><link href="http://www.mycowsworld.com/blog/2013/11/16/sublime-text.html" rel="alternate" type="text/html" title="Sublime Text" /><published>2013-11-16T00:18:00-05:00</published><updated>2013-11-16T00:18:00-05:00</updated><id>http://www.mycowsworld.com/blog/2013/11/16/sublime-text</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2013/11/16/sublime-text.html"><p><a href="http://www.sublimetext.com">Sublime Text</a> is an awesome text editor that is fast, has a simple interface, and can be customized to your heart’s content. The following links walk through installing some of the more popular plugins.</p>
<h4 id="must-haves">Must-haves</h4>
<ul>
<li><a href="https://sublime.wbond.net">Package Control</a> - A Sublime Text Package Manager. Easily installs and updates Sublime Text plugins.</li>
<li><a href="https://github.com/buymeasoda/soda-theme/">Soda Theme</a> - The Dark Theme is so tasty.</li>
</ul>
<h4 id="references">References</h4>
<ul>
<li><a href="http://blog.alexmaccaw.com/sublime-text">http://blog.alexmaccaw.com/sublime-text</a></li>
<li><a href="http://blog.generalassemb.ly/sublime-text-3-tips-tricks-shortcuts/">http://blog.generalassemb.ly/sublime-text-3-tips-tricks-shortcuts/</a></li>
<li><a href="https://coderwall.com/p/ekwjca">https://coderwall.com/p/ekwjca</a></li>
<li><a href="http://www.slant.co/topics/197/~what-are-your-favorite-plugins-for-sublime-text-2">http://www.slant.co/topics/197/~what-are-your-favorite-plugins-for-sublime-text-2</a></li>
</ul>
<p></p></content><author><name></name></author><category term="Code" /><category term="Tools" /><summary type="html">Sublime Text is an awesome text editor that is fast, has a simple interface, and can be customized to your heart’s content. The following links walk through installing some of the more popular plugins. Must-haves Package Control - A Sublime Text Package Manager. Easily installs and updates Sublime Text plugins. Soda Theme - The Dark Theme is so tasty. References http://blog.alexmaccaw.com/sublime-text http://blog.generalassemb.ly/sublime-text-3-tips-tricks-shortcuts/ https://coderwall.com/p/ekwjca http://www.slant.co/topics/197/~what-are-your-favorite-plugins-for-sublime-text-2</summary></entry><entry><title type="html">HTML Device Orientation Project</title><link href="http://www.mycowsworld.com/blog/2013/11/12/coding-project-added-labyrinth.html" rel="alternate" type="text/html" title="HTML Device Orientation Project" /><published>2013-11-12T22:50:00-05:00</published><updated>2013-11-12T22:50:00-05:00</updated><id>http://www.mycowsworld.com/blog/2013/11/12/coding-project-added-labyrinth</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2013/11/12/coding-project-added-labyrinth.html"><p>For a class assignment, we were asked to create a project that demonstrated the usage of device orientation events. In this project, the device orientation was used to manipulate a “rolling ball” on the screen.</p>
<p>To try the demo, click <a href="http://www.mycowsworld.com/code/Labyrinth">here</a>. Note that the project was programmed such that it only works on a mobile device (e.g. phones, tablets).</p>
<p>For the source code, click <a href="https://github.com/moduli/Labyrinth">here</a>. Click through for more documentation.</p>
<!-- more -->
<h2 id="usage">Usage</h2>
<p>After loading the demo, it will ask you to rotate your device to landscape mode. After rotating, tap the screen to begin, and you can begin tilting your device to move a “marble” around on the screen. Rotating back to portrait mode will “pause” the demo.</p>
<p>Each time you resume the demo from a paused state, it will recalibrate the center position based on how the device is held.</p>
<p>The demo can be found <a href="http://www.mycowsworld.com/assets/code/Labyrinth/">here</a>.</p>
<h2 id="documentation">Documentation</h2>
<h3 id="media-queries">Media Queries</h3>
<p>This project used media queries to determine what kind of device is being used by the user. In CSS, different styles were applied based on the device type. For example, the first block would apply to phones, and the second block would apply to tablets. Note that if using a tablet, it would apply the phone styling first, then also apply the tablet styling on top of it.</p>
<figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="k">@media</span> <span class="n">only</span> <span class="n">screen</span> <span class="n">and</span> <span class="p">(</span><span class="n">min-device-width</span><span class="p">:</span> <span class="m">320px</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">#overlaytext</span> <span class="p">{</span>
<span class="nl">font-size</span><span class="p">:</span> <span class="m">25px</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">@media</span> <span class="n">only</span> <span class="n">screen</span> <span class="n">and</span> <span class="p">(</span><span class="n">min-device-width</span><span class="p">:</span> <span class="m">768px</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">#overlaytext</span> <span class="p">{</span>
<span class="nl">font-size</span><span class="p">:</span> <span class="m">50px</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>In Javascript, I first checked to see if the browser supported this functionality. Then, I added some if statements to determine the device type. I used this to set certain settings that would be more “optimized” for a phone versus a tablet.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">matchMedia</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// PHONE</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">matchMedia</span><span class="p">(</span><span class="s1">'(max-device-width: 767px)'</span><span class="p">).</span><span class="nx">matches</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="c1">// TABLET</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">matchMedia</span><span class="p">(</span><span class="s1">'(max-device-width: 1024px)'</span><span class="p">).</span><span class="nx">matches</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<h3 id="device-orientation-change---portraitlandscape">Device Orientation Change - Portrait/Landscape</h3>
<p>To detect when a device changes orientation (from landscape to portrait and vice versa), I employed the use of the window.onorientationchange event. All modern mobile browsers support this event.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">DeviceOrientationEvent</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do something...</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="c1">// display text that this device does not support device orientation</span>
<span class="p">}</span></code></pre></figure>
<p>Once you have determined that the device supports orientation events, you can then receive notifications of when a device changes orientation and subsequently perform an action.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nb">window</span><span class="p">.</span><span class="nx">onorientationchange</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">switch</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">orientation</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Note: The following numbers don't necessarily work on all devices</span>
<span class="c1">// See http://www.matthewgifford.com/blog/2011/12/22/a-misconception-about-window-orientation/ for more detail</span>
<span class="k">case</span> <span class="o">-</span><span class="mi">90</span><span class="err">:</span> <span class="c1">// landscape</span>
<span class="c1">// do something</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">90</span><span class="err">:</span> <span class="c1">// landscape</span>
<span class="c1">// do something</span>
<span class="k">break</span><span class="p">;</span>
<span class="nl">default</span><span class="p">:</span> <span class="c1">// portrait</span>
<span class="c1">// do something</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">};</span></code></pre></figure>
<h3 id="device-orientation-change---ball-movement">Device Orientation Change - Ball Movement</h3>
<p>In addition to receiving notifications when a device changes orientation from landscape to orientation, you can add a listener to receive notifications whenever a device changes its orientation at all.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">'deviceorientation'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// event.gamma - angle of device around x axis</span>
<span class="c1">// event.beta - angle of device around y axis</span>
<span class="c1">// event.alpha - angle of device around z axis</span>
<span class="p">}</span></code></pre></figure>
<h3 id="animation">Animation</h3>
<p>Instead of using a timer loop to create animations, there is a feature to allow the browser to notify your application when it is ready for the next frame of the animation.</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// obtain a reference to the appropriate function name (this function has different names between browsers)</span>
<span class="c1">// if the browser does not support it, we'll fall back to using a timer loop</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">reqAnimFrame</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">mozRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">webkitRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">msRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">oRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">requestAnimationFrame</span> <span class="o">||</span>
<span class="kd">function</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">setTimeout</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="mi">1000</span> <span class="o">/</span> <span class="mi">60</span><span class="p">);</span>
<span class="p">};</span>
<span class="kd">function</span> <span class="nx">animate</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// draw something here</span>
<span class="nx">reqAnimFrame</span><span class="p">(</span><span class="nx">animate</span><span class="p">);</span> <span class="c1">// call animate function again when browser is ready</span>
<span class="p">}</span>
<span class="c1">// initial animate call</span>
<span class="nx">animate</span><span class="p">();</span></code></pre></figure>
<h2 id="references">References</h2>
<h3 id="media-queries-1">Media Queries</h3>
<ul>
<li><a href="http://www.quirksmode.org/blog/archives/2010/09/combining_meta.html">http://www.quirksmode.org/blog/archives/2010/09/combining_meta.html</a></li>
<li><a href="http://www.javascriptkit.com/dhtmltutors/cssmediaqueries2.shtml">http://www.javascriptkit.com/dhtmltutors/cssmediaqueries2.shtml</a></li>
</ul>
<h3 id="device-orientation">Device Orientation</h3>
<ul>
<li><a href="http://www.html5rocks.com/en/tutorials/device/orientation/">http://www.html5rocks.com/en/tutorials/device/orientation/</a></li>
<li><a href="http://www.matthewgifford.com/blog/2011/12/22/a-misconception-about-window-orientation/">http://www.matthewgifford.com/blog/2011/12/22/a-misconception-about-window-orientation/</a></li>
</ul>
<h3 id="animation-1">Animation</h3>
<ul>
<li><a href="http://tutorials.jenkov.com/html5-canvas/animation.html">http://tutorials.jenkov.com/html5-canvas/animation.html</a></li>
<li><a href="http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/">http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/</a></li>
</ul></content><author><name></name></author><category term="Code" /><category term="HTML" /><category term="Javascript" /><category term="CSS" /><summary type="html">For a class assignment, we were asked to create a project that demonstrated the usage of device orientation events. In this project, the device orientation was used to manipulate a “rolling ball” on the screen. To try the demo, click here. Note that the project was programmed such that it only works on a mobile device (e.g. phones, tablets). For the source code, click here. Click through for more documentation.</summary></entry><entry><title type="html">Arabian Nights</title><link href="http://www.mycowsworld.com/blog/2013/09/28/arabian-nights.html" rel="alternate" type="text/html" title="Arabian Nights" /><published>2013-09-28T17:27:00-04:00</published><updated>2013-09-28T17:27:00-04:00</updated><id>http://www.mycowsworld.com/blog/2013/09/28/arabian-nights</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2013/09/28/arabian-nights.html"><div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance001.jpg" title="Wedding Hall">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance001.jpg" alt="Wedding Hall" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance001.jpg" title="Wedding Hall" />
<figcaption>Wedding Hall</figcaption>
</figure>
-->
<p>More pictures…</p>
<!-- more -->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance002.jpg" title="Sheikh Zayed Grand Mosque">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance002.jpg" alt="Sheikh Zayed Grand Mosque" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance002.jpg" title="Sheikh Zayed Grand Mosque" />
<figcaption>Sheikh Zayed Grand Mosque</figcaption>
</figure>
-->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance004.jpg" title="Desert Safari">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance004.jpg" alt="Desert Safari" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance004.jpg" title="Desert Safari" />
<figcaption>Desert Safari</figcaption>
</figure>
-->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance005.jpg" title="Dubai Mall Fountain">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance005.jpg" alt="Dubai Mall Fountain" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance005.jpg" title="Dubai Mall Fountain" />
<figcaption>Dubai Mall Fountain</figcaption>
</figure>
-->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance003.jpg" title="Ravi Restaurant">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance003.jpg" alt="Ravi Restaurant" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance003.jpg" title="Ravi Restaurant" />
<figcaption>Ravi Restaurant</figcaption>
</figure>
-->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance008.jpg" title="Arc de Triomphe du Carrousel">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance008.jpg" alt="Arc de Triomphe du Carrousel" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance008.jpg" title="Arc de Triomphe du Carrousel" />
<figcaption>Arc de Triomphe du Carrousel</figcaption>
</figure>
-->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance006.jpg" title="Notre Dame Cathedral">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance006.jpg" alt="Notre Dame Cathedral" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance006.jpg" title="Notre Dame Cathedral" />
<figcaption>Notre Dame Cathedral</figcaption>
</figure>
-->
<div class="image-wrapper">
<a href="/assets/posts/2013-09-28-arabian-nights/uaefrance007.jpg" title="Louvre Statue">
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance007.jpg" alt="Louvre Statue" />
</a>
</div>
<!--
<figure>
<img src="/assets/posts/2013-09-28-arabian-nights/uaefrance007.jpg" title="Louvre Statue" />
<figcaption>Louvre Statue</figcaption>
</figure>
--></content><author><name></name></author><category term="Photos" /><category term="UAE" /><category term="France" /><category term="Travel" /><summary type="html">More pictures…</summary></entry><entry><title type="html">Setting Up Octopress with Amazon Web Services</title><link href="http://www.mycowsworld.com/blog/2013/08/04/setting-up-octopress-with-amazon-web-services.html" rel="alternate" type="text/html" title="Setting Up Octopress with Amazon Web Services" /><published>2013-08-04T16:48:00-04:00</published><updated>2013-08-04T16:48:00-04:00</updated><id>http://www.mycowsworld.com/blog/2013/08/04/setting-up-octopress-with-amazon-web-services</id><content type="html" xml:base="http://www.mycowsworld.com/blog/2013/08/04/setting-up-octopress-with-amazon-web-services.html"><p>When I initially had the idea to start a blog, I was looking up how to set up WordPress with Amazon Web Services (AWS) - the web host I decided to use. Somehow, I ended up stumbling into Jekyll, which later led me to Octopress. The post describes the steps needed to set up Octopress with AWS.</p>
<p>There are lots of posts out in the internets that describe other people’s experiences with Octopress. Here are a few…</p>
<ul>
<li><a href="http://hiltmon.com/blog/2013/04/17/18-months-of-octopress/">http://hiltmon.com/blog/2013/04/17/18-months-of-octopress/</a></li>
<li><a href="http://nynim.org/blog/2011/12/19/hello-octopress/">http://nynim.org/blog/2011/12/19/hello-octopress/</a></li>
<li><a href="http://openswitch.org/blog/why-octopress/">http://openswitch.org/blog/why-octopress/</a></li>
</ul>
<p><br />
So how do we get octopress set up with AWS?</p>
<!-- more -->
<h2 id="step-1-install-octopress">Step 1: Install Octopress</h2>
<p>Follow the instructions here: http://octopress.org/docs/setup/</p>
<h2 id="step-2-install-s3_website">Step 2: Install s3_website</h2>
<p>s3_website is a tool used to upload your octopress blog to Amazon S3 (an Amazon Web Service used for web storage). For more information on s3_website, go here: https://github.com/laurilehmijoki/s3_website</p>
<p>In the terminal, enter the following commands:</p>
<figure class="highlight"><pre><code class="language-none" data-lang="none">cd &lt;octopress_blog&gt;
gem install s3_website
s3_website cfg create # creates s3_website.yl (configuration file)</code></pre></figure>
<h2 id="step-3-create-user-in-aws-iam">Step 3: Create User in AWS IAM</h2>
<p>AWS IAM (Identity and Access Management) is used to manage access to your resources in AWS. In this step, we’ll create a user in IAM that will be used by s3_website.</p>
<ol>
<li>Go to https://aws.amazon.com/</li>
<li>Click <strong>My Account / Console</strong> on the top-right of the window and select <strong>AWS Management Console</strong></li>
<li>Click <strong>Services</strong> at the top-left of the window and select <strong>IAM</strong></li>
<li>Click <strong>Users</strong> on the left</li>