0
|
1 \documentclass[a4j,12pt]{jreport}
|
|
2 \usepackage[dvipdfmx]{graphicx}
|
|
3 \usepackage{mythesis}
|
|
4 \usepackage{multirow}
|
1
|
5 \usepackage{ascmac}
|
0
|
6 \usepackage{here}
|
|
7 \usepackage{url}
|
1
|
8 \usepackage{fancyhdr}
|
|
9 \usepackage{float}
|
0
|
10 \usepackage{listings, jlisting}
|
1
|
11 %% \input{dummy} %% font
|
0
|
12
|
|
13 \lstset{
|
|
14 language=java,
|
|
15 tabsize=2,
|
|
16 frame=single,
|
|
17 basicstyle={\ttfamily\footnotesize},%
|
|
18 identifierstyle={\footnotesize},%
|
|
19 commentstyle={\footnotesize\itshape},%
|
|
20 keywordstyle={\footnotesize\bfseries},%
|
|
21 ndkeywordstyle={\footnotesize},%
|
|
22 stringstyle={\footnotesize\ttfamily},
|
|
23 breaklines=true,
|
|
24 captionpos=b,
|
|
25 columns=[l]{fullflexible},%
|
|
26 xrightmargin=0zw,%
|
|
27 xleftmargin=1zw,%
|
|
28 aboveskip=1zw,
|
|
29 numberstyle={\scriptsize},%
|
|
30 stepnumber=1,
|
|
31 numbersep=0.5zw,%
|
|
32 lineskip=-0.5ex,
|
|
33 numbers=left
|
|
34 }
|
|
35 \renewcommand{\lstlistingname}{Code}
|
|
36
|
|
37 \setlength{\itemsep}{-1zh}
|
|
38
|
11
|
39 \title{ゲームエンジンにおける木構造データベースjungleの提案}
|
9
|
40 \title{Proposal of tree structured database Jungle in Game Engine.}
|
0
|
41 \icon{
|
|
42 \includegraphics[width=80mm,bb=0 0 595 642]{fig/ryukyu.pdf} %%元は 642じゃなくて842
|
|
43 }
|
11
|
44 \year{平成29年度 卒業論文}
|
0
|
45 \belongto{琉球大学工学部情報工学科}
|
|
46 \author{135768K 武田 和馬 \\ 指導教員 {河野 真治} }
|
|
47
|
|
48 %% TreeVNC のNATへの対応
|
|
49 %% マルチスクリーン TreeVNC
|
|
50 %% プリアンブルに記述
|
|
51 %% Figure 環境中で Table 環境の見出しを表示・カウンタの操作に必要
|
|
52 %%
|
|
53 \makeatletter
|
|
54 \newcommand{\figcaption}[1]{\def\@captype{figure}\caption{#1}}
|
|
55 \newcommand{\tblcaption}[1]{\def\@captype{table}\caption{#1}}
|
|
56 \makeatother
|
|
57 \setlength\abovecaptionskip{0pt}
|
|
58
|
|
59 \begin{document}
|
|
60
|
|
61 % タイトル
|
|
62 \maketitle
|
|
63 \baselineskip 17pt plus 1pt minus 1pt
|
|
64
|
|
65 \pagenumbering{roman}
|
|
66 \setcounter{page}{0}
|
|
67
|
|
68 \tableofcontents % 目次
|
|
69 \listoffigures % 図目次
|
|
70 \listoftables % 表目次
|
|
71
|
|
72 %以下のように、章ごとに個別の tex ファイルを作成して、
|
|
73 % main.tex をコンパイルして確認する。
|
|
74 %章分けは個人で違うので下のフォーマットを参考にして下さい。
|
|
75
|
|
76 % はじめに
|
|
77
|
2
|
78 % 1章では研究目的を書かない(もったいない)
|
|
79 \chapter{ゲームエンジンにおけるデータベース}
|
0
|
80
|
6
|
81 この章ではデータベースの種類であるRelational DatabaseとNoSQLについて述べる。
|
9
|
82 次に分散システムにおいて重要なCAP定理に触れる。
|
3
|
83
|
6
|
84 \section{Relational Database}
|
0
|
85
|
6
|
86 Relational Database(RDB)は、列と行からなる2次元のテーブルにより実装されるデータベースである。
|
|
87 データ型として文字列、数値、日付、Bool型がある。
|
|
88 RDBはスキーマの決まったデータを扱うことを長所としている。
|
0
|
89
|
6
|
90 RDBは主として使われているデータベースであるが、苦手としている事がある。
|
0
|
91
|
6
|
92 それは、スキーマレスなデータの扱いやマシン台数を増やし処理速度を上げることである。
|
9
|
93
|
|
94 テーブルを水平分割や垂直分割によりデータを分割できるが構造としては複雑化していく。
|
|
95
|
10
|
96 プログラムとデータベースとの間にミスマッチが発生する。
|
|
97 これをインピーダンスミスマッチという。
|
|
98
|
|
99 プログラムではリストやネスト構造によりデータを持つことができる。
|
|
100 しかし、データのネスト構造を許さない第一正規形を要求するRDBとは相容れない。
|
9
|
101
|
10
|
102 ORMapperではデータベースのレコードをプログラム中のオブジェクトにマッピングし扱うことができる。
|
|
103 オブジェクトに対する操作を行うとORMapperがSQLを発行し、処理を行ってくれる。
|
|
104 しかしレコードをプログラム中のオブジェクトを対応させるORMapperの技術でインピーダンスミスマッチの本質的な部分を解決することはできない。
|
|
105
|
12
|
106 \pagenumbering{arabic}
|
|
107
|
|
108 %序論の目安としては1枚半ぐらい.
|
|
109 %英語発表者は,最終予稿の「はじめに」の英訳などを載せてもいいかも.
|
10
|
110
|
|
111 \section{ACIDトランザクション}
|
9
|
112
|
|
113 ACID(Atomicity,Consistency,Isolation,Durability) は
|
|
114 データベースのトランザクションの処理が確実に実行されることを保証するものである\cite{amazonacid}。
|
|
115
|
10
|
116 ほとんどのRDBではACIDトランザクションを保証している。
|
9
|
117
|
|
118 \begin{itemize}
|
|
119 \item Atomicity(原子性)
|
|
120
|
|
121 トランザクションを実行する際に、すべて成功するか、すべて失敗するか。
|
|
122
|
|
123 \item Consistency(一貫性)
|
|
124
|
|
125 トランザクション開始時と終了時にデータが一貫していなければならない。
|
|
126
|
|
127 \item Isolation(独立性)
|
|
128
|
|
129 他のトランザクションによる干渉を受けない。
|
|
130
|
|
131 \item Durability(永続性)
|
|
132
|
|
133 コミットしたトランザクションのデータは保存される。
|
|
134
|
|
135 \end{itemize}
|
0
|
136
|
3
|
137 \section{NoSQL}
|
|
138
|
9
|
139 NoSQLはNot Only SQLの略である。
|
|
140
|
|
141 通常NoSQLデータベースは非リレーショナル型であり、スキームの定義がない\cite{nosql}。
|
10
|
142 そのため、扱うデータの型が決まっていなくても気軽に扱える。
|
9
|
143
|
|
144 \section{CAP定理}
|
|
145
|
|
146 分散システムにおいて、次の3つを同時に保証することは出来ない。
|
|
147
|
|
148 \begin{itemize}
|
|
149 \item Consistency(一貫性)
|
|
150
|
|
151 すべてのノードはクエリが同じならば同じデータを返す。
|
|
152
|
|
153 \item Availability(可用性)
|
|
154
|
|
155 あるノードに障害が発生しても、機能しているノードにより常にデータの読み書きが行える。
|
|
156
|
|
157 \item Partition-tolerance(分断耐性)
|
|
158
|
|
159 ネットワーク障害によりノードの接続が切れてもデータベースは機能し続けることができる。
|
|
160
|
|
161 \end{itemize}
|
|
162
|
|
163 これはCAP定理\cite{cap}と呼ばれる。
|
|
164 データベースを利用する場合はCAP定理を意識しながら選択する。
|
|
165
|
|
166 一貫性と可用性を重視したデータベースがRDBである。
|
|
167 分断耐性を必要とする場合はNoSQLデータベースとなる。
|
|
168
|
|
169 NoSQLデータベースでは一貫性を取るか、可用性を取るかによって選択するデータベースが変わる。
|
|
170 以下にその2つの例を示す。
|
3
|
171
|
10
|
172 \section{MongoDB}
|
9
|
173
|
12
|
174 MongoDB\cite{mongodb}は2009年に公開されたNoSQLのデータベースである。
|
9
|
175 ドキュメント指向型とされ、事前にテーブルの構造を決めておく必要がない。
|
|
176 これをスキーマレスという。
|
|
177
|
|
178 MongoDBはマスター/スレーブ方式のReplicationを採用している。
|
|
179 保存したデータ(マスター)を複数のサーバー(スレーブ)に複製を取る。
|
|
180
|
|
181 スレーブをReadさせることによって負荷分散も可能になる。
|
|
182
|
|
183 また、一台のサーバーにすべてのデータを持たず、複数のサーバーに分割して保持する。
|
|
184 これをShardingという。
|
0
|
185
|
9
|
186 MongoDBはReplocationとShardingにより、分断耐性と一貫性を持つ。
|
|
187
|
10
|
188 \section{Cassandra}
|
9
|
189
|
|
190 Cassandra\cite{cassandra}は2008年にFacebookによって公開されたKey-Value型のデータベースである。
|
|
191 AmazonのDynamo\cite{amazonacid}とGoogleのBigTable\cite{bigtable}を合わせた特徴を持っている。
|
|
192 Key-Valueであるため、スキーマレスなNoSQLとなる。
|
|
193
|
|
194 Bigtableから採用した、カラムファミリーと呼ばれる構造を基本としている。
|
|
195
|
|
196 カラムファミリーの行の部分はHashMapや連想配列のようにKey-Valueで複数格納している。
|
|
197
|
|
198 1つのKey-Valueの組をカラムと呼ぶ。
|
|
199 RDBとは異なり、カラム名を事前に定義する必要がない。
|
|
200
|
10
|
201 Cassandraではサーバーノードの配置にConsistent hasingアルゴリズムを用いる。
|
|
202 また、これによりサーバー同士が理論上リング構造になっている。
|
|
203
|
|
204 Consistency Hashingによるリングの形成を図\ref{cassandra_ring}に示す.
|
|
205
|
|
206 \begin{figure}[h]
|
|
207 \begin{center}
|
|
208 \includegraphics[width=10cm]{images/cassandra_ring.pdf}
|
|
209 \caption{Consisteyncy hashingによるring型トポロジーの形成}
|
|
210 \label{cassandra_ring}
|
|
211 \end{center}
|
|
212 \end{figure}
|
|
213
|
|
214 Cassandraはデータを最大どれだけ配置するかを示すReplication factorと, データの読み書きをいくつのノードから行うのかを決めるConsistency Levelの設定が行える。
|
|
215 Consistency Levelには主に ONE, QUORAM, ALL がある。
|
9
|
216
|
10
|
217 Replication factorの数値をNとした場合, ONE は1つのノード, QUORUMは N/2 + 1 のノード, ALLはNのノードへと読み書きを行う。
|
|
218 Replication factorとConsistentcy Levelの設定により, Cassandraは最新のデータを取得したいときと
|
|
219 そうでないときで読み込みと書き込みの速度をあげることができる。
|
|
220 一貫性が重要なデータに関してはQUORUMにより書き込み読み込みを行うことで常に最新のデータを取得することができる。
|
|
221 多少データが古くてもよい場合はONEなどを使用することでレスポンスを早くすることができる。
|
|
222 Consistency Level QUORUMの時のデータ書き込みと読み込みについて図\ref{quorum_write}と図\ref{quorum_read}に示す。
|
|
223 Consistencyハッシング, Replication factorとConsistency Levelの設定により Cassandra は高い可用性と分断耐性を持つ。
|
|
224
|
|
225 \begin{figure}[h]
|
|
226 \begin{center}
|
|
227 \includegraphics[width=10cm]{images/cassandra_quorum_write.pdf}
|
|
228 \caption{Consisteyncy Level QUORUMによる書き込み}
|
|
229 \label{quorum_write}
|
|
230 \end{center}
|
|
231 \end{figure}
|
|
232
|
|
233 \begin{figure}[h]
|
|
234 \begin{center}
|
|
235 \includegraphics[width=10cm]{images/cassandra_quorum_read.pdf}
|
|
236 \caption{Consisteyncy Level QUORUMによる読み込み}
|
|
237 \label{quorum_read}
|
|
238 \end{center}
|
|
239 \end{figure}
|
0
|
240
|
3
|
241 \section{Jungleの提案}
|
6
|
242
|
10
|
243 この章の前半ではRDBとNoSQLの利点と問題点を取り上げた。
|
|
244
|
8
|
245 非破壊的木構造データベースのJungleを提案している\cite{jungle}。
|
6
|
246 Jungleはスケーラビリティのあるデータベースとして開発している。
|
|
247
|
|
248 ウェブサイトの構造は大体が木構造であるため、データ構造として木構造を採用している。
|
|
249 しかし、ウェブサイトだけでなくゲームにおいてもデータ構造が木構造になっている。
|
0
|
250
|
12
|
251 そこで、本研究ではJungleの木構造である特性を活かし、ゲームエンジンUnity\cite{unity}で作成したゲームで使用する方法を提案する。
|
9
|
252
|
6
|
253 データベースとしてJungle Databaseを採用する。
|
9
|
254
|
6
|
255 JungleはJavaとHaskellによりそれぞれの言語で開発されている。
|
|
256 本研究で扱うのはJava版をC\#で再実装したものである。
|
2
|
257
|
|
258 \chapter{Jungle Database の概念}
|
|
259
|
6
|
260 本章ではまずはJungle Databaseの概念と構造について記述する。
|
3
|
261
|
|
262 \section{木構造データベースJungle}
|
|
263
|
2
|
264 当研究室で開発しているJungleは過去の木を保存しつつ、新しい木を構成する手法を採用している。
|
|
265 これを非破壊的木構造という。
|
|
266 非破壊的木構造により、データベースを参照する側と更新する側のデータを安全に扱うことができる。
|
|
267
|
|
268 JungleDatabaseは木の集合からなり、名前で管理される。
|
|
269 木はノードの集合から出来ている。
|
|
270 ノードにはKeyとValueの組からなるデータを持つことができる。
|
|
271 これはデータベースのレコードに相当する。
|
|
272
|
|
273 通常のデータベースと違う点として子のノードを持つことである。
|
|
274
|
|
275 Jungleは、データの変更を一度生成した木を上書きせず、ルートから編集を行うノードまでのコピーを行い、新しく木構造を構築し、そのルートをアトミックに入れ替える{図\ref{nonDestractTreeEdit}}。
|
|
276 これを非破壊的木構造と呼ぶ。非破壊木構造は新しい木を構築している時にも、現在の木を安全に読み出せるという大きな特徴がある。
|
|
277 しかし、書き込みの手間は大きくなる。
|
|
278
|
|
279 \begin{figure}[h]
|
|
280 \begin{center}
|
|
281 \includegraphics[height = 3cm , bb=0 0 511 188]{images/nonDestractTreeEdit.pdf}
|
|
282 \caption{非破壊的木構造の木の編集}
|
|
283 \label{nonDestractTreeEdit}
|
|
284 \end{center}
|
|
285 \end{figure}
|
|
286
|
|
287 \section{Jungle Database の構造}
|
|
288
|
|
289 非破壊木構造を採用しているJungleでは、木の変更の手間はO(1)からO(n)となり得る。
|
|
290 つまりアプリケーションに合わせて木を設計しない限り充分な性能を出すことは出来ない。
|
|
291 逆に木の設計を行えば高速な処理が可能である。
|
|
292
|
|
293 Jungleはオンメモリで使用することを考えており、一度木のルートを取得すれば、その上で木構造として自由にアクセスしてもよい。
|
|
294
|
|
295 Jungleはcommit logを持ち、それを他のノードやディスクに転送することにより、分散構成と持続性を実現する。
|
|
296
|
5
|
297 \chapter{JungleDatabaseのAPI}
|
2
|
298
|
5
|
299 本章ではJungleDatabaseのAPIを記述する。
|
|
300
|
|
301 \section{Jungleの木}
|
2
|
302
|
|
303 Jungleは複数の木の名前を利用し、管理しており、名前により生成、編集を行う。
|
|
304 以下にJungleクラスが提供している木の生成、管理を行うAPI(表\ref{jungleTree})に記述する。
|
|
305
|
|
306 \begin{table}[htb]
|
|
307 \begin{center}
|
|
308 \caption{Jungleに実装されているAPI}
|
5
|
309 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
2
|
310 {\tt JungleTree createNewTree(string treeName) } & Jungleに新しく木を生成する。木の名前が重複した場合、生成に失敗しnullを返す。 \\ \hline
|
|
311 {\tt JungleTree getTreeByName(string treeName)} & JungleからtreeNameと名前が一致するtreeを取得する。名前が一致するTreeがない場合取得は失敗しnullを返す \\ \hline
|
5
|
312 \end{tabular}
|
2
|
313 \label{jungleTree}
|
|
314 \end{center}
|
|
315 \end{table}
|
|
316
|
5
|
317 \section{TreeNode}
|
2
|
318
|
|
319 Jungleが保有する木は、複数のノードの集合で出来ている。
|
|
320 ノードは、自身の子のList、属性名と属性値の組のデータを持つ。
|
|
321 ノードに対するアクセスは表\ref{treeNodeAPI}に記述されているAPIを用いて行う。
|
|
322
|
|
323 \begin{table}[htb]
|
|
324 \begin{center}
|
|
325 \caption{TreeNodeに実装されているAPI}
|
5
|
326 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
2
|
327 {\tt Children getChildren()} & ノードの子供を扱うChildrenオブジェクトを返す。\\ \hline
|
|
328 {\tt Attribute getAttribute()} &ノードが保持しているデータを扱うAttribteオブジェクトを返す。 \\ \hline
|
|
329 \end{tabular}
|
|
330 \label{treeNodeAPI}
|
|
331 \end{center}
|
|
332 \end{table}
|
|
333
|
5
|
334 \section{Either}
|
2
|
335
|
|
336 jungleでは例外処理を投げる時にEitherクラスを用いて行う。返って来たEitherのオブジェクトに対して、{\tt isA() }で{\tt Error}かどうかをチェックする。
|
|
337 {\tt Error}でない場合は{\tt b()}で対象のオブジェクトを取り出す事ができる。
|
|
338
|
|
339 以下にルートノードの2番目の子どもを取ってくるのEitherのサンプルコードを記述する。
|
|
340
|
8
|
341 \begin{itembox}[l]{SaveData.cs}
|
|
342 \scriptsize{
|
|
343 \begin{verbatim}
|
2
|
344 Either<Error,TreeNode> either = children.at(2);
|
|
345 if (either.isA())
|
|
346 return either.a();
|
|
347 TreeNode child = either.b();
|
8
|
348 \end{verbatim}
|
|
349 }
|
|
350 \end{itembox}
|
2
|
351
|
5
|
352 \section{ChildrenとAttribute}
|
2
|
353
|
|
354 Childrenクラスへのアクセスは表\ref{Children}に記述されているAPIを、Attributeクラスへアクセスは表\ref{Attribute}に記述されているAPIを用いて行う。
|
|
355
|
|
356 \begin{table}[htb]
|
|
357 \begin{center}
|
|
358 \caption{Childrenに実装されているAPI}
|
5
|
359 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
2
|
360 {\tt int size()} & 子供の数を返す。\\ \hline
|
|
361 {\tt <Either Error,TreeNode> at(int num)} &ノードが持つ子供の中から、 変数{\tt num}で指定された位置にある子ノードを返す。 \\ \hline
|
|
362 \end{tabular}
|
|
363 \label{Children}
|
|
364 \end{center}
|
|
365 \end{table}
|
|
366
|
|
367 \begin{table}[htb]
|
|
368 \begin{center}
|
|
369 \caption{Attributeに実装されているAPI}
|
5
|
370 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
2
|
371 {\tt T get<T>(string key)} &ノードが持つ値から、属性名 {\tt key}とペアの属性値を{\tt Generic}型で返す。 \\ \hline
|
|
372 {\tt string getString(string key)} &ノードが持つ値から、属性名 {\tt key} とペアの属性値を{\tt string}型で返す。 \\ \hline
|
|
373 \end{tabular}
|
|
374 \label{Attribute}
|
|
375 \end{center}
|
|
376 \end{table}
|
|
377
|
5
|
378 \section{NodePath}
|
2
|
379
|
|
380 Jungleでは、木のノードの位置を{\tt NodePath}クラスを使って表す。
|
|
381 {\tt NodePath}クラスはルートノードからスタートし、対象のノードまでの経路を、数字を用いて指し示すことで対象のノードの場所を表す。また、ルートノードは例外として-1と表記される。
|
|
382 {\tt NodePath}クラスが{\tt < -1,1,2,3>} を表している際の例を図\ref{NodePath}に記す。
|
|
383 \begin{figure}[h]
|
|
384 \begin{center}
|
|
385 \includegraphics[height = 6cm , bb=0 0 568 455]{images/nodePath.pdf}
|
|
386 \caption{NodePath}
|
|
387 \label{NodePath}
|
|
388 \end{center}
|
|
389 \end{figure}
|
|
390
|
5
|
391 \section{木の編集}
|
2
|
392
|
|
393 Jungleの木の編集は{\tt JungleTreeEditor}クラスを用いて行われる。
|
|
394 {\tt JungleTreeEditor}クラスには編集を行うために、表\ref{editor}に記述されているAPIを用いて行う。
|
|
395
|
|
396 \begin{table}[htb]
|
|
397 \begin{center}
|
|
398 \caption{Editorに実装されているAPI}
|
5
|
399 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
2
|
400 {\tt Either<Error, JungleTreeEditor> addNewChildAt( NodePath path, int pos)} &
|
|
401 変数{\tt path}で指定した場所にある、ノードの子供の変数{\tt pos}で指定した位置子ノードを追加する\\ \hline
|
|
402 {\tt Either<Error, JungleTreeEditor> deleteChildAt( NodePath path, int pos)} &
|
|
403 変数{\tt path}で指定した場所にある、ノードの子供の変数{\tt pos}で指定した位置の子ノードを削除する。 \\ \hline
|
8
|
404 {\tt Either<Error, JungleTreeEditor> putAttribute( NodePath path, string key, object value)} &
|
|
405 変数{\tt path}で指定した場所にあるノードに、属性名 変数{\tt key} 属性値 変数{\tt value}で値を挿入する。 \\ \hline
|
2
|
406 {\tt Either< Error, JungleTreeEditor> deleteAttribute( NodePath path, string key)}&
|
8
|
407 変数{\tt path}で指定した場所にあるノードが持つ、属性名 変数{\tt key}で保存されているデータを削除する。\\ \hline
|
2
|
408 {\tt Either<Error, JungleTreeEditor> commit()} &
|
|
409 木へ行った変更をコミットする。自分が編集を行っていた間に、他のJungleTreeEditorクラスによって木が更新されていた場合、コミットは失敗する。 \\ \hline
|
|
410 \end{tabular}
|
|
411 \label{editor}
|
|
412 \end{center}
|
|
413 \end{table}
|
|
414
|
|
415 編集を行った後は、関数{\tt editor.commit()}で今までの編集をコミットすることができる。他の{\tt JungleTreeEditor}クラスによって木が更新されていた場合はコミットは失敗し、{\tt commit()}は{\tt Error}を返す。
|
|
416 その場合は、木の編集を最初からやり直す必要がある。
|
|
417
|
|
418
|
0
|
419
|
|
420 \label{chap:introduction}
|
|
421
|
|
422 \chapter{Unityでのデータベースの取扱い}
|
|
423 \label{chap:concept}
|
|
424
|
3
|
425 この章ではゲームにおけるデータについて述べ、その後Jungleとの関係性や実装を記述する。
|
|
426
|
|
427 \section{ゲームのデータ}
|
9
|
428
|
|
429 ゲームを開発する際にデータの種類について知っておく必要がある。
|
|
430 以下にゲームにおけるデータを記述する。
|
3
|
431
|
4
|
432 %% Attonさんの論文に書いてたitemizeを使うといいかも箇条書きっぽいかきかた。
|
9
|
433 \begin{itemize}
|
|
434 \item オブジェクトが単体で持つデータ
|
|
435
|
|
436 シーン内に存在するオブジェクトが持つパラメータ
|
|
437 例えばプレイヤーのHPや経験値、位置座標などを示す。
|
|
438
|
|
439 \item オブジェクト1つで複数持つデータ
|
|
440
|
|
441 プレイヤーが持つアイテムデータなどを示す。
|
|
442
|
|
443 \item マスタデータ(ReadOnly)\cite{gamedata}\cite{gamedata2}
|
|
444
|
|
445 アイテムの名前や敵の出現確率などを示す。
|
|
446 ゲーム開発者のみが更新できる。
|
|
447
|
|
448 \end{itemize}
|
3
|
449
|
6
|
450 \section{ゲームデータとデータベース}
|
|
451
|
9
|
452 ゲームのデータベースとして使われているのがRDBである。
|
6
|
453
|
10
|
454 1章で述べたようにRDBとプログラム間ではインピーダンスミスマッチという問題がある。
|
6
|
455
|
10
|
456 ここではゲームでのインピーダンスミスマッチの例を紹介する。
|
|
457
|
|
458 ゲーム中のユーザが持つアイテムという単純なものでも、RDBではユーザとアイテムの組をキーとする巨大な表として管理することになる。
|
6
|
459 % ネストを許さないのは第一正規形だけ
|
|
460 プログラム中では、ユーザが持つアイテムリストという簡単な構造を持つが、第一正規形を要求するRDBではネスト構造を許さない。
|
|
461
|
0
|
462 \section{UnityとJungleの関係}
|
|
463
|
|
464 Unityは3Dゲームエンジンで、ゲームを構成する要素(Object)をC\#で制御する。
|
|
465 Objectは一つのゲームのシーン(一画面の状況)の中で木構造を持つ。
|
|
466 これをシーングラフと言う。
|
|
467 シーングラフをそのままJungleに格納するという手法が考えられる。
|
|
468
|
|
469 \section{Unityにおけるデータベース}
|
|
470
|
3
|
471 Unityでのデータベースとして考えられるものとしてはSQLite3、PlayerPrefsが挙げられる。
|
2
|
472
|
|
473 PlayerPrefsとは、Unityに特化したバイナリ形式でKeyとValueのみで保存されるものである。
|
|
474 セーブ機能に特化していてメモリ上にDBを展開するものではない。
|
0
|
475
|
2
|
476 SQLite3ではC\#で利用できるORMapperが提供されている。
|
|
477 プログラム中からデータのインサートやデリートを行う。
|
|
478
|
3
|
479 %% 思いついたこと入れた UnityでのJsonのお話
|
|
480 Unity5.3以降のバージョンでは標準でJsonが扱えるようになった。
|
|
481 これにより、インスタンスをJson化することができる。
|
|
482
|
0
|
483 \chapter{Jungle-Sharpの実装}
|
|
484
|
12
|
485 JavaとC\#はよく似た言語であり、移行する方法を確立した。
|
0
|
486 Jungleの中心部分である木構造とIndexを構成する赤黒木のコードはほぼ変更なく移行できた。
|
|
487 C\#ではインナークラスが使えないので明示的なクラスに変換する必要があった。
|
|
488
|
|
489 \section{AtomicRefarenceの実装}
|
|
490
|
8
|
491 Jungleの木の変更(commit)はCAS(Check and Set)を用いてatomicに行われる。競合している書き込み中に自分の書き込みが成功した場合に関数\verb+commit()+が成功する。
|
9
|
492 失敗した場合ははじめからもう一度行う。
|
0
|
493
|
5
|
494 JavaではAtomicRefarenceが標準であるがC\#にはなかったためAtomicRefarenceのクラスを新たにつくった。
|
0
|
495
|
5
|
496 \begin{itembox}[l]{AtomicRefarence.cs}
|
0
|
497 \scriptsize{
|
|
498 \begin{verbatim}
|
|
499 // C#
|
|
500 public bool CompareAndSet(T newValue, T prevValue) {
|
|
501 T oldValue = value;
|
|
502 return (oldValue
|
|
503 != Interlocked.CompareExchange
|
|
504 (ref value, newValue, prevValue));
|
|
505 }
|
|
506
|
|
507 // Java
|
|
508 AtomicRefarence<T> atomic = new AtomicRefarence<T>();
|
|
509 atomic.compareAndSet(prevValue, newValue);
|
|
510
|
|
511 \end{verbatim}
|
|
512 }
|
|
513 \end{itembox}
|
|
514
|
1
|
515
|
0
|
516 \section{Listの実装}
|
|
517
|
|
518 木やリストをたどる時にJavaではIteratorを用いる。
|
|
519 Iteratorは次の値があるかを返すboolean hasNext()と、Tという型の次の値を取ってくるT next()を持つObjectである。
|
|
520 C\#では木やリストを辿りながらyeildで次の値を返す。
|
|
521 Javaでは以下のように実装されている。
|
|
522
|
|
523 \begin{itembox}[l]{List.java}
|
|
524 \scriptsize{
|
|
525 \begin{verbatim}
|
|
526 public Iterator<T> iterator() {
|
|
527 return new Iterator<T>() {
|
|
528 Node<T> currentNode = head.getNext();
|
|
529
|
|
530 @Override
|
|
531 public boolean hasNext() {
|
|
532 return currentNode.getAttribute()
|
|
533 != null;
|
|
534 }
|
|
535
|
|
536 @Override
|
|
537 public T next() {
|
|
538 T attribute
|
|
539 = currentNode.getAttribute();
|
|
540 currentNode
|
|
541 = currentNode.getNext();
|
|
542 return attribute;
|
|
543 }
|
|
544 };
|
|
545 }
|
|
546 \end{verbatim}
|
|
547 }
|
|
548 \end{itembox}
|
|
549
|
|
550 C\#ではIEnumeratorがあるのでそれを利用した。
|
|
551 ListのforeachではIteratorを呼び出すために、一つずつ要素を返す必要がある。
|
|
552 yield returnステートメントを利用することで位置が保持され、次に呼ばれた際に続きから値の取り出しが可能になる。
|
|
553 以下にその実装例を示す。
|
|
554
|
|
555 \begin{itembox}[l]{List.cs}
|
|
556 \scriptsize{
|
|
557 \begin{verbatim}
|
|
558 public IEnumerator<T> iterator() {
|
|
559 Node<T> currentNode = head.getNext();
|
|
560 while (currentNode.getAttribute() != null) {
|
|
561 yield return (T)currentNode.getAttribute();
|
|
562 currentNode = currentNode.getNext ();
|
|
563 }
|
|
564 }
|
|
565 \end{verbatim}
|
|
566 }
|
|
567 \end{itembox}
|
|
568
|
2
|
569 \section{bindの実装}
|
0
|
570
|
2
|
571 Jungleではデータの編集を行った後、Eitherを用いてエラーのチェックを行う。
|
|
572 エラーがあればエラーが包まれたEitherが返される。
|
|
573 エラーがない場合は指定した型のオブジェクトがEitherに包まれて返される。
|
0
|
574
|
2
|
575 これは関数型プログラミング言語、Haskellから採用したものである。
|
0
|
576
|
2
|
577 編集を行うたび、Eitherのチェックbindで行うことにより、より関数型プログラミングに特化した書き方が可能になる。
|
|
578 C\#で実装したbindは以下に記述する。
|
0
|
579
|
2
|
580 \begin{itembox}[l]{DefaultEither.cs}
|
|
581 \scriptsize{
|
|
582 \begin{verbatim}
|
|
583 public Either<A, B> bind (System.Func<B, Either<A, B>> f) {
|
|
584 if (this.isA ()) {
|
|
585 return this;
|
|
586 }
|
0
|
587
|
2
|
588 return f (this.b ());
|
|
589 }
|
|
590 \end{verbatim}
|
|
591 }
|
|
592 \end{itembox}
|
0
|
593
|
8
|
594 bindでのEitherをチェックしつつデータを格納する例を以下に記述する。
|
5
|
595
|
2
|
596 \begin{itembox}[l]{DataSaveTest.cs}
|
|
597 \scriptsize{
|
|
598 \begin{verbatim}
|
10
|
599 Item apple = new Item("Apple");
|
0
|
600
|
10
|
601 either = either.bind ((JungleTreeEditor arg) => {
|
|
602 return arg.addNewChildAt (rootPath, 0);
|
|
603 });
|
0
|
604
|
10
|
605 either = either.bind ((JungleTreeEditor arg) => {
|
|
606 return arg.putAttribute (apple);
|
|
607 });
|
|
608
|
2
|
609 \end{verbatim}
|
|
610 }
|
|
611 \end{itembox}
|
0
|
612
|
9
|
613 bindの実装により、ユーザ側でEitherのErrorチェックを行う必要がなくなる。
|
2
|
614
|
0
|
615
|
|
616 \chapter{Unityで実装したアプリケーション}
|
|
617
|
3
|
618 本章ではUnityで実際に作成したアプリケーションを示し、どのようにデータの設計を行ったかを述べる。
|
|
619
|
10
|
620 \section{例題のゲーム}
|
2
|
621
|
0
|
622 本論文ではC\#で再実装を行ったJungleをUnityで作られたゲームの上に構築する。
|
8
|
623 例題のゲームとしては図\ref{craft}に記載した、マインクラフト\cite{minecraft}の簡易版を作成する。
|
0
|
624
|
|
625 \begin{figure}[h]
|
|
626 \begin{center}
|
9
|
627 \includegraphics[width=10cm]{images/craft.png}
|
0
|
628 \caption{craft}
|
|
629 \label{craft}
|
|
630 \end{center}
|
|
631 \end{figure}
|
|
632
|
2
|
633 プレイヤーは自由にマップを移動し、ステージの破壊や、生成を行うことができる。
|
|
634 破壊や生成のオペレーションに合わせてJungleのノードにも同期する。
|
|
635 この同期も非破壊で行われる。
|
|
636
|
10
|
637 \section{ゲームを構成する要素}
|
2
|
638
|
|
639 例題ゲームを構成するゲームの要素を記述する。
|
|
640
|
|
641 Unityではオブジェクトに対してコンポーネントが紐付けられる。
|
9
|
642 クラスはMonoBehaviourを継承している場合のみコンポーネントして扱える。
|
2
|
643 %% ただし、MonoBehaviourを継承している場合インスタンスを生成することができない。
|
|
644
|
|
645 ステージを構成するブロックのコンポーネントして、ItemBoxクラスを紐付ける。
|
9
|
646 ItemBoxの持つ変数を表\ref{itemboxes}に示す。
|
2
|
647
|
|
648 \begin{table}[htb]
|
|
649 \begin{center}
|
9
|
650 \caption{ItemBoxクラスが持つパラメータ}
|
|
651 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
|
652 int {\tt Broken }&
|
|
653 Itemの耐久力、0になると自身のItemBoxのオブジェクトを破壊\\ \hline
|
|
654 Color {\tt ColorCode} &
|
2
|
655 自身のブロックの色 \\ \hline
|
|
656 \end{tabular}
|
9
|
657 \label{itemboxes}
|
|
658 \end{center}
|
|
659 \end{table}
|
|
660
|
|
661 ステージ上に回復アイテムをランダムに配置する。
|
|
662 回復アイテムにはコンポーネントとして、ItemFoodクラスを紐付ける。
|
|
663 ItemFoodが持つ変数を表\ref{itemfood}に示す。
|
|
664
|
|
665 \begin{table}[htb]
|
|
666 \begin{center}
|
10
|
667 \caption{ItemFoodクラスが持つパラメータ}
|
9
|
668 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
|
669 string {\tt Name} &
|
|
670 食べ物の名前 \\ \hline
|
|
671 int {\tt Recovery}&
|
|
672 アイテムを取得時に回復する数\\ \hline
|
|
673 \end{tabular}
|
|
674 \label{itemfood}
|
2
|
675 \end{center}
|
|
676 \end{table}
|
|
677
|
|
678 プレーヤーにはコンポーネントとしてPlayerクラスを紐付ける。
|
|
679 Playerクラスの持つ変数を表\ref{player}に示す。
|
|
680
|
|
681 \begin{table}[htb]
|
|
682 \begin{center}
|
9
|
683 \caption{Playerクラスが持つパラメータ}
|
|
684 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
|
685 int {\tt HP }&
|
2
|
686 プレイヤーの体力、0になるとゲームオーバー\\ \hline
|
9
|
687 List {\tt ItemList} &
|
2
|
688 プレイヤーが持つアイテムのリスト \\ \hline
|
|
689 \end{tabular}
|
|
690 \label{player}
|
|
691 \end{center}
|
|
692 \end{table}
|
|
693
|
10
|
694 \section{データの設計}
|
0
|
695
|
2
|
696 Unityにおけるゲームの構成はObjectの親子関係、つまり木構造である。
|
9
|
697 同じくJungle Databaseは木構造である。
|
|
698 % Unityでシーンを構成する際にデータの設計を気にしなくてもいい。
|
|
699
|
|
700 Jungleでは複数の木を持つことができる。
|
|
701 ゲームのシーンを構成するGameTreeとアイテムを管理するItemTreeをJungle内に作る。
|
2
|
702
|
9
|
703 ItemTreeは第4章で述べたマスターデータとして扱う。
|
|
704
|
10
|
705 GameTreeではシーン内にあるPlayerやStageを構成するCubeなどを格納している。
|
2
|
706 図\ref{GameTree}ではJungleに格納する構造を示したものである。
|
|
707
|
9
|
708
|
2
|
709 \begin{figure}[h]
|
|
710 \begin{center}
|
9
|
711 \includegraphics[width=10cm]{images/Tree.pdf}
|
2
|
712 \caption{GameTree}
|
|
713 \label{GameTree}
|
|
714 \end{center}
|
|
715 \end{figure}
|
|
716
|
9
|
717 Jungleではオブジェクトが単体で持つデータとオブジェクトが複数持つデータを同時に表現できる。
|
|
718
|
|
719 ノード1つのAttributeに対してデータを格納する。
|
|
720 図\ref{GameTree}のようにPlayerが持つアイテムを表現したい場合はPlayerノードの子としてHaveItemノードを作る。
|
|
721 HaveItemノードの子として持っているアイテムを子ノードとすればよい。
|
|
722
|
|
723 ItemTreeではItemの情報が格納されている。
|
|
724 図\ref{ItemTree}ではJungleに格納しているItemの構造を示したものである。
|
|
725
|
|
726 \begin{figure}[h]
|
|
727 \begin{center}
|
|
728 \includegraphics[width=10cm]{images/ItemTree.pdf}
|
|
729 \caption{ItemTree}
|
|
730 \label{ItemTree}
|
|
731 \end{center}
|
|
732 \end{figure}
|
|
733
|
|
734 ItemTreeではRootノードはItemのTypeが書かれた子ノードを持っている。
|
10
|
735 子ノードはStageを構成するBox Type、回復アイテムとするFood Typeの2種類である。
|
2
|
736
|
11
|
737 \section{ゲームエンジンに特化したデータベース}
|
2
|
738
|
10
|
739 C\#の再実装を行った際にJavaのJungleに沿ってデータの型、つまりByteArrayで設計を行っていた。
|
9
|
740
|
5
|
741 データの格納を行うたびにByte Arrayへのキャストを行う必要がある。
|
|
742 しかし、キャストの処理は軽くはない。
|
|
743
|
|
744 そこで、シーンを構成するObjectをそのまま格納するに仕様を変更した。
|
|
745 C\#ではObjectクラスのエイリアスとしてobject型が使える。
|
|
746
|
|
747 object型を使うことによってユーザーが定義した任意の変数を代入することができる。
|
|
748 以下にその使用例を記述する。
|
|
749
|
|
750 \begin{itembox}[l]{SaveData.cs}
|
|
751 \scriptsize{
|
|
752 \begin{verbatim}
|
|
753 Player player = new Player ();
|
|
754 either = either.bind ((JungleTreeEditor arg) => {
|
|
755 return arg.putAttribute ("Player", player);
|
|
756 });
|
2
|
757
|
5
|
758 Enemy enemy = new Enemy ();
|
|
759 either = either.bind ((JungleTreeEditor arg) => {
|
|
760 return arg.putAttribute ("Enemy", enemy);
|
|
761 });
|
|
762 \end{verbatim}
|
|
763 }
|
|
764 \end{itembox}
|
|
765
|
|
766 % as演算子はbyte arrayにするよりも早いのでOK?か?
|
|
767 データを取り出すにはGenericで型を指定する、もしくはas演算子を用いてキャストを行う。
|
|
768 以下に取り出す例を記述する。
|
|
769
|
|
770 \begin{itembox}[l]{SaveData.cs}
|
|
771 \scriptsize{
|
|
772 \begin{verbatim}
|
|
773 Player player = attr.get<Player> ("Player");
|
|
774 Enemy enemy = attr.get ("Enemy") as Enemy;
|
|
775 \end{verbatim}
|
|
776 }
|
|
777 \end{itembox}
|
|
778
|
|
779 データの型の再設計を行ったことによりシーン内のオブジェクトをそのまま格納が可能になった。
|
|
780 格納の際にByte Arrayに変換する必要がない。
|
9
|
781
|
5
|
782 分散構造や、ネットワークで必要な時だけ変換する。
|
2
|
783
|
11
|
784 \chapter{Jungle-Sharpの評価}
|
2
|
785
|
9
|
786 本章ではC\#とJava版Jungleとの比較、Jungle-SharpとUnity上で使われるSQLite3、PlayerPrefsとの比較を行う。
|
0
|
787
|
|
788 \section{Javaとの比較}
|
|
789
|
2
|
790 本論文ではJavaで書かれたJungle DatabaseをC\#で再実装した。
|
8
|
791 同じオペレーションでJavaとC\#で計測する。
|
2
|
792 なお、1回目の処理はキャッシュを作り処理が遅くなるため、計測は行わず、2回目以降から行う。
|
8
|
793 計測時に使用したデータ挿入のオペレーションを以下に記述する。
|
|
794
|
|
795 % 単一のベンチマーク
|
|
796 \begin{itembox}[l]{BenchMarkmark.cs}
|
2
|
797 \scriptsize{
|
|
798 \begin{verbatim}
|
8
|
799 for (int i = 0; i < trial; i++) {
|
|
800 Either<Error, JungleTreeEditor> either = edt.addNewChildAt (path, i);
|
|
801 either = either.bind ((JungleTreeEditor arg) => {
|
|
802 return arg.putAttribute ("name", "Kazuma");
|
|
803 });
|
|
804 }
|
2
|
805 \end{verbatim}
|
|
806 }
|
|
807 \end{itembox}
|
|
808
|
8
|
809 計測に使用したマシンの環境を記述する。
|
|
810
|
|
811 \begin{table}[htb]
|
|
812 \begin{center}
|
|
813 \caption{計測環境}
|
|
814 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
|
815 OS &
|
|
816 Mac OS Sierra 10.12.3 \\ \hline
|
|
817 Memory &
|
|
818 8 GB 2133 MHz LPDDR3 \\ \hline
|
|
819 CPU &
|
|
820 2.9 GHz Intel Core i5 \\ \hline
|
|
821 Java &
|
|
822 1.8.0111 \\ \hline
|
|
823 .NET Runtimes (MonoDevelop-Unity) &
|
|
824 Mono 4.0.5 \\ \hline
|
|
825 .NET Runtimes (Xamarin) &
|
|
826 Mono 4.6.2 \\ \hline
|
|
827 \end{tabular}
|
|
828 \label{itembox}
|
|
829 \end{center}
|
|
830 \end{table}
|
|
831
|
2
|
832 %% データの図を入れる
|
|
833
|
8
|
834 計測結果を図\ref{BenchMark}に示す。
|
|
835
|
|
836 \begin{figure}[h]
|
|
837 \begin{center}
|
9
|
838 \includegraphics[width = 10cm]{images/benchmark.pdf}
|
8
|
839 \caption{BenchMark}
|
|
840 \label{BenchMark}
|
|
841 \end{center}
|
|
842 \end{figure}
|
|
843
|
9
|
844 Jungleでは木構造を変更する計算量として、O(1)からO(n)が期待される。
|
|
845
|
11
|
846 図\ref{BenchMark}より、Unityで実行した結果ではO(n)のグラフを示している。
|
8
|
847 Unityではレンダリングの機能も兼ねている。
|
|
848 そのためプログラムを実行している間もレンダリングを行っているため、
|
|
849 純粋なPutAttributeの計算時間ではないと考えられる。
|
|
850
|
|
851 XamarinはC\#の性能を確認するために実行した。
|
11
|
852 C\#で再実装したJungleはJava版とほぼ同じ計算量を示している。
|
|
853
|
8
|
854
|
|
855 % なんでか?みたいなお話
|
|
856 % プリミティブ型?データ型?
|
|
857 % Javaは純粋オブジェクト指向言語ではないから?
|
|
858 % if文が遅い?
|
|
859 % Lambda式だから早い? - いや遅い気がする
|
2
|
860
|
|
861 \section{SQLite3とPlayerPrefsとの比較}
|
|
862
|
|
863 Unityで使われているデータ保存としてSQLite3とPlayerPrefsがある。
|
8
|
864 それぞれに対し、データの格納を100回行い、測定する。
|
|
865
|
|
866 以下にJungle、SQLite3、PlayerPrefsでのデータ挿入を行うサンプルコードを記述する。
|
|
867
|
|
868 % 単一のベンチマーク
|
|
869 \begin{itembox}[l]{BenchMarkmark.cs}
|
|
870 \scriptsize{
|
|
871 \begin{verbatim}
|
|
872
|
|
873 // Jungle
|
|
874 for (int i = 0; i < TrialCount; i++) {
|
|
875 either.bind ((JungleTreeEditor arg) => {
|
|
876 return arg.putAttribute (rootPath ,"Player_" + i, HP);
|
|
877 });
|
|
878 }
|
|
879
|
|
880 either.bind ((JungleTreeEditor arg) => {
|
|
881 return arg.commit();
|
|
882 });
|
|
883
|
|
884 // SQLite3
|
|
885 for (int i = 0; i < TrialCount; i++) {
|
|
886 sql.ExecuteNonQuery ("insert into player values("+ i + "," + HP + " )");
|
|
887 }
|
2
|
888
|
8
|
889 // PlayerPrefs
|
|
890 for (int i = 0; i < TrialCount; i++) {
|
|
891 PlayerPrefs.SetInt ("Player_" + i, HP);
|
|
892 }
|
|
893 PlayerPrefs.Save ();
|
|
894 \end{verbatim}
|
|
895 }
|
|
896 \end{itembox}
|
|
897
|
|
898 Jungleは挿入後、\tt{commit()}を行うまでを挿入とする。
|
|
899
|
|
900 PlayerPrefsは\tt{Save()}を行うとバイナリに書き出される。
|
|
901 そこまでを挿入とする。
|
|
902
|
|
903 計測結果を以下に記述する。
|
|
904
|
|
905 \begin{table}[htb]
|
|
906 \begin{center}
|
|
907 \caption{実行結果}
|
|
908 \begin{tabular}{|p{14em}|p{14em}|} \hline
|
|
909 Jungle &
|
|
910 12.217ms \\ \hline
|
|
911 SQLite3 &
|
|
912 126.265ms \\ \hline
|
|
913 PlayerPrefs &
|
|
914 985.131ms \\ \hline
|
|
915 \end{tabular}
|
|
916 \label{itembox}
|
|
917 \end{center}
|
|
918 \end{table}
|
|
919
|
|
920 Jungleはデータを直接プログラム内部、つまりオンメモリに持っている。
|
|
921 そのため通信を行わずにデータのやり取りができる。
|
|
922
|
|
923 SQLite3ではデータを挿入のSQLを実行するたびデータベースとの通信を行うため遅くなっている。
|
9
|
924
|
8
|
925 PlayerPrefsはデータをまとめてセットすることができる。
|
|
926 しかし、バイナリ形式で保存されるため、書き出す時間がかかってしまう。
|
0
|
927
|
|
928 \chapter{結論}
|
|
929 \section{まとめ}
|
|
930
|
10
|
931 本研究ではJungleDatabaseをC\#で再実装を行った。
|
2
|
932 JavaとC\#は比較的似ている言語であるため移行は難しくはなかった。
|
0
|
933
|
8
|
934 性能としてもJava版に劣らない、もしくはそれ以上のパフォーマンスを出せる。
|
9
|
935
|
8
|
936 Eitherでのbindの実装で、より関数型プログラミングを意識しながら記述することができる。
|
|
937 これはJava版にはない実装である。
|
|
938
|
|
939 Jungle DatabaseはもともとWeb向けに作られたデータベースである。
|
9
|
940
|
12
|
941 Webでは頻繁にデータが書き換わることは多くない。
|
|
942 しかしゲームでは扱うデータが頻繁に書き換わる。
|
8
|
943
|
|
944 そのため、Jungleの構成は保ちつつ、ゲームに合わせたJungleの拡張を行った。
|
9
|
945
|
8
|
946 データの格納の際にByteBufferであったものをObject型に変更した。
|
|
947 これにより、シーンを構成するObjectを手間なく格納することを可能にした。
|
|
948
|
|
949 Jungleは非破壊であるため、過去の変更を持っている。
|
9
|
950
|
8
|
951 ゲームにおいて過去の木を持ち続けることはパフォーマンスの低下につながる。
|
|
952 そのため、過去の木をどこまで必要かを検討しなければならない。
|
|
953
|
|
954 現在C\#版のJungleにはデータを永続化させる仕組みは備わっていない。
|
|
955 実用的なゲームのデータベースとして使うためには永続化を実装する必要がある。
|
0
|
956
|
|
957 %\section{Alice での実装}
|
|
958
|
|
959 % 参考文献
|
|
960 \def\line{−\hspace*{-.7zw}−}
|
|
961 \nocite{*}
|
|
962 \bibliographystyle{junsrt}
|
|
963 \bibliography{reference}
|
|
964
|
|
965
|
|
966 \chapter*{謝辞}
|
|
967 \thispagestyle{empty}
|
|
968
|
|
969 %基本的な内容は以下の通り.参考にしてみて下さい.
|
|
970 %厳密な決まりは無いので,個々人の文体でも構わない.
|
|
971 %GISゼミや英語ゼミに参加した人はその分も入れておく.
|
|
972 %順番は重要なので気を付けるように.(提出前に周りの人に確認してもらう.)
|
|
973
|
|
974 \hspace{1zw}本研究の遂行,また本論文の作成にあたり、御多忙にも関わらず終始懇切なる御指導と御教授を賜わりました河野真治准教授に深く感謝致します。
|
|
975
|
2
|
976 数々の貴重な御助言と細かな御配慮を戴いた金川 竜己さん、比嘉健太さん、伊波立樹さん、並びに並列信頼研究室の皆様に深く感謝致します。
|
0
|
977
|
|
978 最後に、有意義な時間を共に過ごした情報工学科の学友、並びに物心両面で支えてくれた両親に深く感謝致します。
|
|
979
|
|
980 \begin{flushright}
|
|
981 2017年 3月 \\ 武田和馬
|
|
982 \end{flushright}
|
|
983
|
|
984 % 付録
|
|
985
|
|
986 \end{document}
|