Wikibooks
jawikibooks
https://ja.wikibooks.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8
MediaWiki 1.39.0-wmf.21
first-letter
メディア
特別
トーク
利用者
利用者・トーク
Wikibooks
Wikibooks・トーク
ファイル
ファイル・トーク
MediaWiki
MediaWiki・トーク
テンプレート
テンプレート・トーク
ヘルプ
ヘルプ・トーク
カテゴリ
カテゴリ・トーク
Transwiki
Transwiki‐ノート
TimedText
TimedText talk
モジュール
モジュール・トーク
Gadget
Gadget talk
Gadget definition
Gadget definition talk
高等学校の学習
0
572
205820
205299
2022-07-25T06:01:05Z
Kwawe
68789
/* 高等学校の教科書目録一覧 */
wikitext
text/x-wiki
{{Pathnav|メインページ|小学校・中学校・高等学校の学習|frame=1}}
ここでは高校の教科書を中心に収録しています。現行課程・新課程(令和4年度以降)になってからの改訂作業が大幅に遅れているため、[[高等学校の学習/旧課程|旧課程]]の教科書を参照せざるをえない教科も多くあります。あしからずご了承ください。また、改訂作業をお手伝いいただける方はご協力ください。
__TOC__
{{進捗状況}}
== 高等学校の教科書目録一覧 ==
[[検定教科書/高等学校|高等学校の検定教科書一覧]]{{進捗|75%|2022-07-25}}
※現在、普通科の教科書は全て掲載済みとなります。
<u>工業・商業・水産の検定教科書については2022年8月末までに掲載予定です。</u>
また、リンク先は、2022年以降入学された現高校1年生で使う教科書です。
== 普通教育に関する各教科・科目と標準単位数 ==
=== [[高等学校国語|国語]] ===
==== 2021年度以前 ====
* [[高等学校国語総合|国語総合]] 4単位{{進捗|25%|2014-12-23}}
* [[高等学校国語表現|国語表現]] 3単位
* [[高等学校現代文A|現代文A]] 2単位{{進捗|00%|2012-12-21}}
* [[高等学校現代文B|現代文B]] 4単位 {{進捗|00%|2014-11-24}}
* [[高等学校古典A|古典A]] 2単位 {{進捗|25%|2012-12-21}}
* [[高等学校古典B|古典B]] 4単位 {{進捗|25%|2014-12-22}}
==== 2022年度以降 ====
* [[高等学校現代の国語|現代の国語]]
* [[高等学校言語文化|言語文化]]
* [[高等学校国語表現|国語表現]]
* [[高等学校論理国語|論理国語]]
* [[高等学校文学国語|文学国語]]
* [[高等学校古典探究|古典探究]]
'''関連項目'''
* [[高等学校古文]]
=== [[高等学校地理歴史|地理歴史]] ===
==== 2021年度以前 ====
* [[高等学校世界史A|世界史A]] 2単位 {{進捗|50%|2012-12-21}}
* [[高等学校世界史B|世界史B]] 4単位 {{進捗|75%|2018-05-04}}
* [[高等学校日本史A|日本史A]] 2単位{{進捗|00%|2018-07-31}}
* [[高等学校日本史B|日本史B]] 4単位 {{進捗|50%|2018-06-06}}
* [[高等学校地理A|地理A]] 2単位
* [[高等学校地理B|地理B]] 4単位 {{進捗|25%|2018-06-11}}
==== 2022年度以降 ====
* [[高等学校歴史総合|歴史総合]]
* [[高等学校地理総合|地理総合]]
* [[高等学校世界史探究|世界史探究]]
* [[高等学校日本史探究|日本史探究]]
* [[高等学校地理探究|地理探究]] 4単位 {{進捗|25%|2022-07-17}}
===[[高等学校公民|公民]]===
(現在、新課程に対応する公民の教科書は執筆途中です。当面の間は[[/旧課程|/旧課程]]の教科書で代用してください)
==== 2021年度以前 ====
* [[高等学校現代社会|現代社会]] 2単位 {{進捗|25%|2013-09-30}}
* [[高等学校倫理|倫理]] 2単位 {{進捗|00%|2013-09-30}}
* [[高等学校政治経済|政治経済]] 2単位 {{進捗|00%|2013-09-30}}
==== 2022年度以降 ====
* [[高等学校公共|公共]] {{進捗|25%|2022-06-24}}
* [[高等学校倫理|倫理]]
* [[高等学校政治経済|政治経済]]
=== [[高等学校数学|数学]] ===
(2021年入学生までの旧課程に対応する数学の教科書は[[高等学校数学]]を参照してください)
* [[新課程高等学校数学I|数学I]] 3単位
* [[新課程高等学校数学II|数学II]] 4単位
* [[新課程高等学校数学III|数学III]] 3単位
* [[新課程高等学校数学A|数学A]] 2単位
* [[新課程高等学校数学B|数学B]] 2単位
* [[新課程高等学校数学C|数学C]] 2単位
=== [[高等学校理科|理科]] ===
(現在、現行・新課程に対応する理科の教科書は執筆途中です。当面の間は[[/旧課程|/旧課程]]の教科書で代用してください。)
* [[高等学校理科 科学と人間生活|科学と人間生活]] 2単位
* [[高等学校理科 物理基礎|物理基礎]] 2単位 {{進捗|00%|2013-09-30}}
* [[高等学校理科 化学基礎|化学基礎]] 2単位
* [[高等学校 生物基礎|生物基礎]] 2単位
* [[高等学校理科 地学基礎|地学基礎]] 2単位
* [[高等学校 物理|物理]] 4単位 {{進捗|25%|2022-06-27}}
* [[高等学校 化学|化学]] 4単位 {{進捗|25%|2022-6-2}}
* [[高等学校 地学|地学]] 4単位
*[[高等学校 生物|生物]] 4単位 {{進捗|50%|2022-07-09}}
* [[高等学校理科 理科課題研究|理科課題研究]] 1単位
=== [[高等学校外国語|外国語]] ===
(現在日本語版ウィキブックスには現行課程に対応する外国語科の教科書はありません。当面の間は[[/旧課程|/旧課程]]の教科書で代用してください)
* コミュニケーション英語Ⅰ 3単位
* コミュニケーション英語Ⅱ 4単位
* コミュニケーション英語Ⅲ 4単位
* コミュニケーション英語基礎 2単位
* 英語表現Ⅰ 2単位
* 英語表現Ⅱ 4単位
* 英語会話 2単位
* 英語以外の外国語に関する科目
'''関連項目'''
* [[高校英語の文法]]
=== [[高等学校保健体育|保健体育]] ===
* [[高等学校保健体育体育|体育]] 7~8単位
* [[高等学校保健体育保健|保健]] 2単位 {{進捗|25%|2013-09-30}}
=== [[高等学校芸術|芸術]] ===
* [[高等学校音楽I|音楽I]] 2単位
* [[高等学校美術I|美術I]] 2単位
* [[高等学校工芸I|工芸I]] 2単位
* [[高等学校書道I|書道I]] 2単位
=== [[高等学校家庭|家庭]] ===
* [[高等学校家庭基礎|家庭基礎]] 2単位 {{進捗|00%|2013-09-30}}
* [[高等学校家庭総合|家庭総合]] 4単位
* 生活デザイン 4単位
=== [[高等学校情報|情報]] ===
==== 2021年度以前 ====
* [[高等学校情報/社会と情報|社会と情報]] 2単位 {{進捗|25%|2016-06-10}}
* [[高等学校情報/情報の科学|情報の科学]] 2単位 {{進捗|25%|2016-06-10}}
==== 2022年度以降 ====
* [[高等学校情報I|情報I]] 2単位
* [[高等学校情報II|情報II]] 2単位
=== [[総合的な学習の時間]] ===
3~6単位(2単位まで減可)
== 専門教育に関する各教科 ==
* [[高等学校農業]] {{進捗|00%|2013-09-30}}
* [[高等学校工業]] {{進捗|25%|2013-09-23}}
* [[高等学校商業]] {{進捗|00%|2013-09-30}}
* [[高等学校水産]] {{進捗|00%|2013-09-30}}
* [[高等学校家庭]] {{進捗|00%|2013-09-30}}
* [[高等学校看護]] {{進捗|00%|2013-09-30}}
* [[高等学校情報]] {{進捗|00%|2013-09-30}}
* [[高等学校福祉]] {{進捗|00%|2013-09-30}}
* [[高等学校理数]] {{進捗|00%|2013-09-30}}
* [[高等学校体育]] {{進捗|00%|2013-09-30}}
* [[高等学校音楽]] {{進捗|00%|2013-09-30}}
* [[高等学校美術]] {{進捗|00%|2013-09-30}}
* [[高等学校英語]] {{進捗|00%|2013-09-30}}
== 特別活動 ==
* [[高等学校ホームルーム活動]]
* [[高等学校生徒会活動・委員会活動]]
* [[高等学校学校行事]]
== 課外活動 ==
* [[高等学校部活動]] {{進捗|25%|2013-09-30}}
* [[高等学校ボランティア活動]]
== 関連項目 ==
* [[高校生活ガイド]]
* [[大学受験ガイド]] {{進捗|25%|2013-09-30}}
* [[学習方法#高等学校|学習方法]]
[[Category:高等学校教育|*]]
ipd5l1slh7xjzustlbu2zbxgxk73eqv
DOS入門
0
579
205823
176222
2022-07-25T07:00:19Z
もなー(偽物)
65472
PC-9800シリーズ用コマンドリファレンスを作成とその他細部の加筆を行いました。
wikitext
text/x-wiki
MS-DOS/PC DOS入門は、マイクロソフト社製のMS-DOS、IBM社製のPC DOSおよびそのほかのDOSに関する解説である。
{{Wikipedia|MS-DOS}}
<!-- DOS -->
== MS-DOS、PC DOSとは? ==
MS-DOS、PC DOSは、パーソナルコンピュータ(PC)において、グラフィカルユーザインターフェイス([[w:GUI|GUI]])が普及するまで用いられたIntel 8086(x86)アーキテクチャ用キャラクタインターフェイス([[w:CUI]])オペレーティングシステムである。詳しくは、姉妹プロジェクトのウィキペディアの[[w:MS-DOS|MS-DOS]]を参照。
== MS-DOS、PC DOSの歴史 ==
IBMが初代IBM PC用のOSの開発を米国マイクロソフト本社に委託し、PC DOSが開発された。その後、PC DOSをベースにマイクロソフトが他社にOEM供給したものは、MS-DOSとされた。
また、Microsoftに許諾を取った上でIBM PC(後のPC/ATアーキテクチャ)以外の多くのアーキテクチャ向けに他社が移植を行っている。(PC-9800シリーズなど)
=== DOSの変遷 ===
; MS-DOS
: バージョン1からバージョン6(Windows 95/98のDOS部分はバージョン7とされる)
; PC DOS
: バージョン1からバージョン7(バージョン7に若干の改修を加えたPC DOS 2000も存在する)
; [[w:DR-DOS|DR DOS]]
: バージョン3.31からバージョン7.03 (バージョン8.1は[[w:GNU General Public License|GPL]]違反により消滅)
バージョン6以降、MS-DOS、PC DOSの次世代CUI OSとしてMS OS/2,IBM OS/2が開発されたが、Windowsの登場によりあまり普及しなかった。
=== 現代のDOS ===
MS-DOS、PC DOSは、オペレーティングシステムとしてはほとんど使われなくなったが、Microsoft Windowsのコマンドプロンプトとして、また、[[w:Microsoft Windows Vista|WindowsVista]]から([[w:Windows XP|WindowsXP]]からインストール可能)は、[[w:cmd.exe|コマンドプロンプト]]の他に[[w:Windows PowerShell|Windows PowerShell]]が標準に追加され、そのコマンド体系は残っている。
その他、有志によってFreeDOSやDOSBOX等、MS-DOSの互換OSが生まれた。
== DOSの概念 ==
DOSは、'''D'''isk '''O'''perating '''S'''ystemの略称であることからもわかるように、基本的にフロッピーディスク・ハードディスク上で運用しその記憶媒体上のデータを操作することにより使用する。
=== ディスク・ファイル ===
; ディスクドライブ (A, B, C, D, ... Z)
: ディスクドライブには「ドライブレター」というアルファベットのドライブ文字が割り当てられ、「Aドライブ」などと呼ぶ。[[w:PC/AT|PC/AT]]アーキテクチャではフロッピーディスクドライブにはAまたはBの文字が、ハードディスクドライブやCD-ROMドライブにはC以降の文字が割り当てられる。[[w:PC-9800シリーズ|PC-98]]アーキテクチャでは、フロッピーディスク、ハードディスクを問わず起動ドライブがAドライブとなり、その後B、C、Dと順番に割り当てられていく。CONFIG.SYSのLASTDRIVEで上限を設定できる。<br> なお、現代のパソコンで内蔵ドライブの多くがCドライブになるのは、このMS-DOSの設定で、A・Bドライブが[[w:フロッピーディスクドライブ|フロッピーディスクドライブ]]、更に詳しく書くと、AドライブがMS-DOSのフロッピーディスク用のドライブ、Bドライブがその他のフロッピーディスク用のドライブ用で、Cドライブが[[w:ハードディスク|ハードディスクドライブ]]用と割り振られているからである。決してCドライブの"C"は「computer」の"C"ではない。コンピューターの記憶装置として普及したフロッピーディスクから順番に割り振っていったらハードディスクのドライブレターが"C"になったということにすぎない。なお、フロッピーディスクドライブがA・Bと二つ割り振られているのは、当時、AドライブでMS-DOSを読み込みながらBドライブのフロッピーディスクの作業をしていたからである。<br> また、[[w:ソリッドステートドライブ|SSD]]は[[w:ハードディスク|ハードディスクドライブ]]の代替であるから、ハードディスクドライブと同じCドライブである。
; カレントドライブ
: カレントドライブとは、対象となっているドライブのことである。カレントディレクトリとともに操作対象のディレクトリを指定する。「C:」や「D:」などのコマンドで変更できる。
; ディレクトリ
: ファイルを階層化して管理する概念としてディレクトリと呼ばれるものがある。バージョン1には、ディレクトリの概念がない。なお[[w:Windows|Windows]]ではフォルダと呼ぶ。
; カレントディレクトリ
: カレントディレクトリとは、対象となっているディレクトリのことである。各ドライブごとに存在し、それぞれを内部コマンドのCDで変更できる。
; [[w:ファイルシステム|ファイルシステム]]
: FAT ([[w:File Allocation Table|File Allocation Table]]) を用いる。FATは[[w:Microsoft Windows 95|Windows 95]]でファイル名の長さ制限を256バイトにした[[w:File Allocation Table#VFAT|VFAT]]に拡張された。なお、VFATをDOS/Vフォーマット、IBMフォーマットなどと呼ぶこともある。<sup><span title="要出典">''<nowiki>[</nowiki>[[w:Wikipedia:「要出典」をクリックされた方へ|<span title="要出典">要出典</span>]]<nowiki>]</nowiki>''</span></sup><!-- VFATはDOS/Vでは正しく扱えないためDOS/Vフォーマットと呼ばれるには疑問が残る.またPC-DOSではVFATはサポートされたことがないためIBMフォーマットと呼ばれるのも疑問. -->
: また[[w:NTFS|NTFS]]などのパーティションにアクセスするためのドライバも販売されていた。
<!--
「ディスクフォーマット」と言いながらフロッピーディスクの種類に言及しているため一旦オミット.
フォーマットの違いだけでなく磁性体の違いなどもあるため不適当.
; ディスクフォーマット
: ディスクフォーマットは、ファイルシステムを含むディスク上のデータを記録する形式のことである。
:* 2DD - 640KB, 720KB
:* 2HD - 1.21MB, 1.25MB, 1.44MB
:* 2ED - 2.88MB (2EDはほとんど普及しなかった)
: 現在、普及しているフロッピーディスクのフォーマットは、DOS/V 1.44MB 2HDが主であり、1995年以前の日本ではPC-9800シリーズ用の1.25MB 2HDが使われたが、Windowsの登場以降では1.44MB 2HDに移行した。
-->
=== 起動プロセス ===
次の順にファイルを読み込む。
* <tt>IO.SYS</tt> (必須)
* <tt>MSDOS.SYS</tt> (必須)
* <tt>CONFIG.SYS</tt>
* <tt>COMMAND.COM</tt> (変更可)
* <tt>AUTOEXEC.BAT</tt>
{|class='wikitable'|
|style='text-align: center;'|<tt>IO.SYS</tt>
|style='text-align: center;'|→
|style='text-align: center;'|<tt>MSDOS.SYS</tt>
|style='text-align: center;'|→
|rowspan='2' style='text-align: center;'|<tt>CONFIG.SYS</tt><br/>(省略可)
|rowspan='2' style='text-align: center;'|→
|rowspan='2' style='text-align: center;'|シェル<br/>(省略時<tt>COMMAND.COM</tt>)
|rowspan='2' style='text-align: center;'|→
|rowspan='2' style='text-align: center;'|<tt>AUTOEXEC.BAT</tt><br/>(省略可)
|-
|style='text-align: center;'|<tt>IBMBIO.COM</tt>
|style='text-align: center;'|→
|style='text-align: center;'|<tt>IBMDOS.COM</tt>
|style='text-align: center;'|→
|}
なお、PC DOSまたはDR DOSの場合には<tt>IO.SYS</tt>は<tt>IBMBIO.COM</tt>に,<tt>MSDOS.SYS</tt>は<tt>IBMDOS.COM</tt>
となる。また、<tt>AUTOEXEC.BAT</tt>は<tt>COMMAND.COM</tt>から呼び出されるため、<tt>CONFIG.SYS</tt>において<tt>SHELL</tt>変数を<tt>COMMAND.COM</tt>以外を指定した場合には読み込まれない。
== 環境設定 ==
<tt>CONFIG.SYS</tt>と<tt>AUTOEXEC.BAT</tt>を書き換えることで行う。
MS-DOSバージョン7では、<tt>MSDOS.SYS</tt>も用いる。
=== <tt>CONFIG.SYS</tt> ===
==== デバイスドライバ ====
<tt>DEVICE</tt>、<tt>DEVICEHIGH</tt>文によって組み込む。
主なデバイスドライバには次のものがある。
*メモリ管理ドライバ
** [[Wikipedia:XMS|XMS]]ドライバ (<tt>HIMEM.SYS</tt>)
** [[Wikipedia:Expanded_Memory_Specification|EMS]]ドライバ (<tt>EMM386.EXE</tt>)
*** 互換ドライバとして[[Wikipedia:QEMM|QEMM]]などが開発・販売された
* マウスドライバ (<tt>MOUSE.SYS</tt>)
** NEC PC-98シリーズ版MS-DOSでのみ提供されている
** PC/AT互換機用のDOSでは常駐プログラムとして<tt>MOUSE.COM</tt>が提供されている
* 日本語フロントエンドプロセッサ (FEP)
具体的には
: <tt>DEVICE=C:\DOS\HIMEM.SYS</tt>
などのように記述する。
なお、<tt>DEVICEHIGH</tt>文を用いる場合には、Upper Memory Blocksを使用するため、<tt>HIMEM.SYS</tt>またはそれに準ずるドライバを<tt>DEVICE</tt>文で読み込んだ後に使用しなければならない。
==== 常駐プログラムの読み込み ====
日本語FEPやマウスドライバなどの常駐プログラムを<tt>CONFIG.SYS</tt>から読み込む場合には、
<tt>INSTALL</tt>文または<tt>INSTALLHIGH</tt>文を使う 。
<tt>INSTALL</tt>文を使うことで、
<tt>AUTOEXEC.BAT</tt>を使わずに設定ファイルを構成することもできるが、
歴史的経緯から<tt>INSTALL</tt>文はあまり使われない。
なお、
<tt>DEVICE</tt>文における<tt>DEVICEHIGH</tt>文と同じく、
Upper Memory Blocksを使う関係上<tt>HIMEM.SYS</tt>の読み込みよりも後に<tt>INSTALLHIGH</tt>を使わなければならない。
; 例 : <tt>INSTALL=C:\DOS\MOUSE.COM</tt>
==== シェル設定 ====
<tt>SHELL</tt>文によって設定する。
通常は標準シェルである<tt>COMMAND.COM</tt>を使用する。
具体的には
: <tt>SHELL=C:\COMMAND.COM /P</tt>
などのように記述する。
なお、末尾の<tt>/P</tt>は必須。
==== その他 ====
* <tt>DOS</tt>文<br/>システムの一部をHigh Memory AreaやUpper Memory Blocksに読み込む際に使用する。
** <tt>HIGH</tt> ... High Memory Areaに読み込む
** <tt>UMB</tt> ... Upper Memory Blocksに読み込む
; 例 : <tt>DOS=HIGH,UMB</tt>
* <tt>DOSDATA</tt>文<br/>PC DOS 7.0以降のみ使用可能。
; 例 : <tt>DOSDATA=UMB</tt>
=== <tt>AUTOEXEC.BAT</tt> ===
<tt>AUTOEXEC.BAT</tt>は<tt>COMMAND.COM</tt>が起動時に必ず読み込むファイルである。
実体は通常のバッチファイルになっている。
このファイルには常駐プログラムやDOSの起動時に自動的に実行させたいアプリケーションを書きこむ。
主に使われる用途としては次のようなものがある。
* ディスクキャッシュ
* CD-ROMドライブ名の割り当て
** DOSでCD-ROMドライブを使うためには、デバイスドライバの読み込みだけではなく、<tt>MSCDEX.EXE</tt>などの常駐ソフトウェアが必要になる
* Windowsを起動させる (Windows 3.xまで)
記述方法は絶対パスもしくは相対パスで行う。
具体的には
: A:\WINDOWS\WIN.COM
: .\WINDOWS\WIN.COM
などのように記述する。
なお、常駐ソフトウェアを読み込む際には<tt>CONFIG.SYS</tt>の<tt>DEVICE</tt>文に対する<tt>DEVICEHIGH</tt>文のように、
High Memory Areaに常駐させるための<tt>LOADHIGH</tt>文 (省略記法: <tt>LH</tt>) が用意されている。
=== MSDOS.SYS ===
MSDOS.SYSはCONFIG.SYS、AUTOEXEC.BATと違い、編集できる場所が限られている。もし、編集してはならない場所を編集した場合、MS-DOSが起動できなくなるケースが多い。
主に以下の用途で使われる。
:*デフォルトシェル
:*起動ドライブ
:*インストールディレクトリ
:*Windows起動中のロゴを表示させる。(Windows9x)
= コマンド =
DOSのコマンドは、
'''内部コマンド'''と'''外部コマンド'''
に大別される。
内部コマンドとは標準シェル<tt>COMMAND.COM</tt>の内蔵コマンドである。
外部コマンドとは<tt>COMMAND.COM</tt>に内蔵されていない、
<tt>.COM</tt>形式あるいは<tt>.EXE</tt>形式で提供されているコマンドである。
<tt>.BAT</tt>形式を使うと、一度に複数のコマンドを実行できる。
== 基本コマンド ==
=== <tt>DIR</tt>について ===
ディレクトリの内容を表示するための内部コマンド (UNIXの<tt>ls</tt>に相当)。
ディレクトリの中身を知りたい場合によく使われる。
(詳しく知りたい場合は、<tt>DIR /?</tt>とコマンドの後に<tt>/?</tt>)
サンプル出力 (全てBochs上のFreeDOSより)
==== <tt>DIR</tt> ====
<pre>
C:\>dir
Volume in drive C is FREEDOS
Volume Serial Number is 4228-11FA
Directory of C:\
KERNEL SYS 41,293 08-04-02 11:32a
COMMAND COM 86,413 07-30-02 12:17a
DOS <DIR> 11-14-02 10:43a
FDCONFIG SYS 263 11-14-02 11:05a
EDIT EXE 62,277 08-11-04 7:38p
EDIT HLP 29,452 04-28-04 1:22a
5 file(s) 219,698 bytes
1 dir(s) 5,402,624 bytes free
C:\>
</pre>
===== <tt>DIR /W</tt> =====
例1:
<pre>
C:\>dir /w
Volume in drive C is FREEDOS
Volume Serial Number is 4228-11FA
Directory of C:\
KERNEL.SYS COMMAND.COM [DOS] FDCONFIG.SYS EDIT.EXE
EDIT.HLP
5 file(s) 219,698 bytes
1 dir(s) 5,402,624 bytes free
C:\>
</pre>
例2:
<pre>
Directory of C:\DOS\BIN
[.] [..] RIPCORD.COM ASSIGN.COM ATTRIB.COM
CHOICE.EXE CMDXSWP.COM COMMAND.COM KSSF.COM PTCHSIZE.EXE
VSPAWN.COM COMP.COM DEBUG.COM DISKCOMP.EXE DISKCOPY.EXE
DISKCOPY.INI DELTREE.COM DELTREE2.COM EDIT.EXE EDIT.HLP
EMM386.EXE HIMEM.EXE EXE2BIN.COM FC.EXE FDISK.EXE
FDISK.INI FDISKPT.INI FDISKB.EXE FDXMS.SYS FDXMST.SYS
FDXXMS.SYS FDXXMST.SYS XMSTEST.EXE FDXM286T.SYS FDXMS286.SYS
XMS2TEST.EXE FIND.EXE FORMAT.EXE FASTHELP.BAT FDHELP.EXE
[FILES] HELP.EXE HELP.HTM LABEL.EXE MEM.EXE
[MKEYB] MIRROR.EXE MODE.COM MORE.EXE MOVE.EXE
NANSI.SYS PRINT.COM PRINTQ.EXE 28MON.COM 2CMON.COM
API28.COM API28I16.COM REPLACE.EXE SCANDISK.EXE SHARE.EXE
CDCACHER.EXE CDHDREAD.EXE KLUDGE0.EXE NBSTAT.EXE SHSUCDHD.EXE
SHSUCDN.EXE SHSUCDX.EXE SHSUDRVX.EXE SHSUSERV.EXE SORT.EXE
JOIN.EXE SUBST.EXE SWSUBST.EXE SYS.COM BITDISK.EXE
TDSK.EXE TREE.COM UNDELETE.EXE UNFORMAT.EXE XCOPY.EXE
[KEY] KEYB.BAT KEYMAN.EXE LISTXDEF.EXE SCANKBD.EXE
XKEYB.EXE XKEYBRES.EXE
82 file(s) 1,872,278 bytes
5 dir(s) 5,402,624 bytes free
C:\DOS\BIN>
</pre>
場合によっては、<tt>DIR</tt>コマンドを入力しても、長すぎて全てを見られないときがある。
例:
<pre>
SHSUCDX EXE 15,726 10-20-00 3:34p
SHSUDRVX EXE 12,849 10-20-00 3:19p
SHSUSERV EXE 113,520 05-09-96 8:12p
SORT EXE 14,816 01-24-95 3:20p
JOIN EXE 54,096 08-05-00 4:07p
SUBST EXE 54,096 08-05-00 4:07p
SWSUBST EXE 54,096 01-26-97 11:35p
SYS COM 10,687 08-16-02 11:29p
BITDISK EXE 10,311 06-22-95 1:10a
TDSK EXE 18,183 12-12-95 2:30a
TREE COM 9,893 07-07-01 12:33p
UNDELETE EXE 9,103 08-30-02 11:30p
UNFORMAT EXE 36,231 03-24-99 8:31p
XCOPY EXE 15,102 09-07-01 12:10a
KEY <DIR> 11-14-02 11:03a
KEYB BAT 23 08-17-01 4:55a
KEYMAN EXE 6,202 04-14-02 2:09p
LISTXDEF EXE 3,366 04-14-02 2:09p
SCANKBD EXE 6,627 04-14-02 2:09p
XKEYB EXE 12,657 07-27-02 6:57p
XKEYBRES EXE 5,986 07-27-02 6:57p
82 file(s) 1,872,278 bytes
5 dir(s) 5,402,624 bytes free
C:\DOS\BIN>
</pre>
そのような場合は、
===== <tt>DIR /P</tt> =====
コマンドを使用する。
このコマンドを使用すると『次の頁を見るためには、何かキーを押してください』と表示されるので、次の頁を見たい場合は、何かキー(Enter等)を押す。
<pre>
Volume in drive C is FREEDOS
Volume Serial Number is 4228-11FA
Directory of C:\DOS\BIN
. <DIR> 11-14-02 10:44a
.. <DIR> 11-14-02 10:44a
RIPCORD COM 5,805 09-04-02 7:20a
ASSIGN COM 13,867 01-27-97 12:46a
ATTRIB COM 7,136 08-01-02 2:00a
CHOICE EXE 12,032 08-31-02 4:20p
CMDXSWP COM 88,043 07-29-02 10:38p
COMMAND COM 86,413 07-29-02 10:42p
KSSF COM 828 07-29-02 10:42p
PTCHSIZE EXE 13,104 07-29-02 10:42p
VSPAWN COM 953 07-29-02 10:42p
COMP COM 1,285 11-27-94 3:48p
DEBUG COM 19,606 11-24-01 7:55p
DISKCOMP EXE 18,688 05-01-01 9:48p
DISKCOPY EXE 46,176 07-15-01 2:17p
DISKCOPY INI 512 07-15-01 2:05p
DELTREE COM 4,210 04-24-00 1:02a
DELTREE2 COM 3,858 04-24-00 1:02a
EDIT EXE 336,449 06-23-01 2:03p
Press any key to continue . . .
</pre>
=== <tt>CD</tt> (<tt>CHDIR</tt>) について ===
'''カレントディレクトリ'''を変更する際に使用するコマンドである。
==== <tt>CD</tt> ====
ディスクA:\BINからの一つ上のフォルダに移動したい時には、
<pre>
A:\BIN>cd ..
A:\>
</pre>
.(ピリオド)は'''カレントディレクトリ'''を表す。
上記の場合、連続してピリオドを記述しているが、これは'''1階層上のディレクトリ'''を指定した事になる。
== コマンドリファレンス ==
MS-DOSのコマンドには、'''内部コマンド'''と'''外部コマンド'''が存在することは前述の通りである。
そのため、以下で外部コマンドとしたものについては、.COM/.EXEのファイルが無ければ使用できないので注意されたし。
以下内部コマンドにはnとつける。
=== 機種共通 ===
*ATTRIB
*:ファイル属性の変更。+R/-R(読みとり専用属性)、+H/-H(隠しファイル属性)、+S/-S(システムファイル属性)、+A/-A(アーカイブ属性)の内操作したい物を記述し、その後に対象のファイル名を指定する。
*CLS
*:画面に表示されている情報を消去する。 n
*COLOR
*:文字色・背景色を設定できる。
*COMMAND
*:COMMAND.COMを起動する。プロンプトから呼び出しても、意味がない。 n
*COPY
*:ファイルをコピーする。コピー元のファイルと、コピー先(別ドライブや別ディレクトリを指定したり、別の名前でコピーを作ったりできる)を指定する。2つ以上のファイルを結合しながらコピーすることもできる。 n
*DEL
*:ファイルの削除。削除対象のファイル名を指定する。 n
*DELTREE
*:指定のディレクトリ以下を全て削除する。
*EXIT
*:COMMAND.COMを終了する。ほかのソフトウェアから呼び出された場合、そのソフトウェアに戻るが、それ以外の場合は何も起こらない。 n
NEC PC-9800シリーズの場合はハードディスクのアクセスアームを元に戻す機能を備えているため、
実行(CTRL+C または STOP キー)して電源を落とさないとハードディスクのデータが破壊される可能性がある。
*FC
*:ファイル比較
*FDISK
*:パーティーションの管理を行う。下手に操作すると、データを失うので、慣れるまでパーティーションの編集はしない。Windows 95(MS-DOS 7)以降。
*FORMAT
*:ディスクのフォーマットを行う。
*INTERLINK
*:DOSレベルで2台のPCをP2P接続するためのソフトウエア。接続にはRS-232Cかパラレルプリンターポートを使う。ホストとなるマシンのHDがゲストとなるPCで操作できるようになる。
*LABEL
*:ドライブのボリュームラベルを変更する。ドライブを指定しその後に新しいボリュームラベルを指定するか、もしくはドライブ名だけ指定してコマンドが出すプロンプトで新しいボリュームラベルを指定する。
*MD(MKDIR)
*:ディレクトリを作成する。作成するディレクトリを指定する。 n
*MEM
*:メモリーの使用状況などを確認できる。
*MODE
*:デバイスの設定を行う。画面のサイズも変更できる。
*MORE
*:1画面毎にキー入力を待つ表示。"<"の後に表示するファイルを指定するか、もしくは他のコマンドの後に"| MORE"を付ける。Windowsでは、ファイル名をパラメーターにすることができる。
*MOVE
*:ファイルの移動。RENと異なり、ディレクトリやドライブを超えた移動ができる。
*PROMPT
*:プロンプト( '''C:\>''' など)を変更する。
*RD(RMDIR)
*:ディレクトリの削除。削除するディレクトリを指定するが、そのディレクトリは空でなければならない。 n
*REN
*:ファイル名の変更。変更したいファイルの場所と、新しい名前を指定する。 n
*SCANDISK
*:ディスクのエラーを検査する。バージョン6以降。それ以前ではCHKDSKを使用することで簡易に情報を見ることが出来る。
*SET
*:環境変数の設定。例えばSET TEMP=C:\TEMPなどとして設定し、その後COPY ''FILENAME'' %TEMP%と実行するとあたかもCOPY ''FILENAME'' C:\TEMPと実行したかのように振舞われる。 n
*SYS
*:DOSシステムの転送。IO.SYS, MSDOS.SYS, COMMAND.COMなどを指定ドライブへコピーするが、バージョンによって転送するファイルに若干の違いがある。
*TIME/DATE
*:マシンの日付及び時刻を設定する。 n
*TREE
*:ディレクトリ構造を表示する。
*TYPE
*:テキストファイルの中身を表示する。 n
*VER
*:DOSのバージョン番号を表示する。
*XCOPY
*:拡張されたCOPYコマンド。ファイルだけではなく、ディレクトリのコピーを行うことができる。
=== NEC PC-9800シリーズ用 ===
以下は、NEC PC-9800シリーズ用MS-DOSに付属する外部コマンドである。特定バージョンにのみ付属するもの、同名でもバージョンにより大きく異なる動作をするものについてはその旨併記している。
スイッチ等をつけずに起動すると独自のウィザード・操作メニューが表示される事が多い。(以下mで表記)
* AVGDRV
*:拡張グラフィックドライバを組み込む。PC-9821シリーズの256色グラフィック機能に対応。そのままでは意味を持たない。
* AVSDRV
*:PC-9801-86相当のPCM・FM音源の拡張サウンドドライバを組み込む。そのままでは意味を持たない。
* BATKEY
*:バッチファイル用。メッセージを表示してキー入力を要求する。
* COPY2
*:ハードディスクとフロッピーディスクとの間でファイルをコピーする。
* COPYA
*: 補助入出力装置との間でデータファイルをコピーする。 m
* CUSTOM
*:CONFIG.SYS(環境設定ファイル)を作成・編集する。 m
* DICM
*:NECかな漢字変換の辞書ファイルのユーザー登録単語を登録・編集する。 m
* DISKCOPY
*:フロッピー・ハードディスクをコピー・照合する。 m
* DUMP
*:ファイルの内容を16進数と文字で表示する。
* FILECONV
*:N88-日本語BASIC(86)とMS-DOSとの間でファイルを交換する。 m
* FDNCOPY
*:フロッピーディスクを高速で全体コピーする。DISKCOPYより空きメモリが必要。m
* FORMAT
*:操作メニューに沿ってディスクのフォーマット・情報閲覧を行う。スイッチをつけると通常と同じように動作する。 m
* HDUTL
*:ハードディスクを診断、スキップセクタの代替処理、全体コピーを行う。 m
* INSTAP
*:アプリケーションをMS-DOS Shellに登録する。MS-DOS Shellを搭載したバージョン以降のみ。 m
* KEY
*:ファンクションキーや移動キーに機能を割り当てる。 m
* MAOIX
*:iスクリプトを使ってアプリケーションを登録する。 m
* MENU
*:メニュー選択方式でコマンドを実行できるコマンドメニューを起動する。 MS-DOS Shellが搭載されていないバージョンでは初期状態で起動時に表示される。 m
* MENUCONV
*:上記MENUコマンド用メニューファイル(*.MNU)に登録されているアプリケーションをMS-DOS Shellに登録する。 m
* MENUED
*:上記MENUコマンド用メニューファイル(*.MNU)を作成・編集する。 m
* NECAIKEY
*:日本語入力キーの割り当てを変更する。 m
* PATCH
*:ファイルの内容の一部を変更する。
* RENDIR
*:既存のディレクトリ名を変更する。
* SEDIT
*:スクリーンエディタ(メモ帳のようなソフト)を起動する。
* SETUP
*:SETUP.INIというアプリケーション登録用定義ファイルを使ってアプリケーションプログラムを登録する。 m
* SPEED
*:RS-232Cインターフェースのパラメータを設定する。 m
* SWITCH
*:メモリスイッチの設定を変更する。 m
* USKCGM
*:ユーザー定義文字を作成・編集する。 m
* VFDDRV
*:仮想FDドライブドライバ。CONFIG.SYSに組み込んで使用。
* VRAMD
*:仮想FDドライブ起動ディスクを作成する。仮想ディスクからの起動はPC-9821An/Ap2/As2/Bf/Bp/Bs/Be/Cs2/Ce2/Xn/Xp/Xs/Xe/Cb/Cx/Cf/Ap3/As3のみ使用可能。 m
<!-- == MS-DOS API == -->
== 参考文献・出典 ==
* 「MS-DOSってなんどすか?」 粟野邦夫著 (1987/01) ISBN 4-89369-014-0
* PC98固有のDOSコマンドについて http://radioc.web.fc2.com/column/pc98bas/pc98doscmd.htm 2022年7月25日15時09分(JST)取得
* NECパーソナルコンピュータ PC-9800シリーズ Software Library MS-DOS(R) 5.0A ステップアップマニュアル 日本電気株式会社(非売品、同社製 MS-DOS(R) 5.0A 標準機能セット(PS98-1003-32/UF1003-X1)付属品)
{{stub}}
{{DEFAULTSORT:MS-DOS/PC-DOSにゆうもん}}
[[Category:ソフトウェアのマニュアル]]
{{NDC|007.63}}
8hn4yq3vz28iygz5yc7jw5nrsvncl73
中学受験参考書
0
762
205834
168108
2022-07-25T08:00:29Z
133.78.37.245
wikitext
text/x-wiki
{{Pathnav|メインページ|小学校・中学校・高等学校の学習|frame=1}}
中学受験参考書の書庫です。
{{進捗状況}}
== 国語 ==
* [[中学受験国語|国語]]{{進捗|25%|2020-08-29}}
== 社会 ==
* [[中学受験社会|社会]]{{進捗|50%|2020-08-30}}
== 算数 ==
* [[中学受験算数|算数]]{{進捗|50%|2020-08-29}}
== 理科 ==
* [[中学受験理科|理科]]{{進捗|25%|2020-08-29}}
== 面接 ==
* [[中学受験面接|面接]]{{進捗|75%|2020-08-29}}
== 演習 ==
* [[中学受験国語/演習|国語]]{{進捗|25%|2020-08-29}}
* [[中学受験社会/演習|社会]]{{進捗|00%|2020-08-29}}
* [[中学受験算数/演習|算数]]{{進捗|75%|2020-08-29}}
* [[中学受験理科/演習|理科]]{{進捗|00%|2020-08-29}}
== 関連項目 ==
* [[中学受験ガイド]]
* [[中学受験参考書/中学校別対策|中学校別の対策]]
[[Category:小学校教育|ちゆうかくしゆけん]]
[[Category:書庫|ちゆうかくしゆけん]]
[[Category:入学試験|ちゆうかくしゆけん]]
[[カテゴリ:中学受験参考書|*]]
6to1cb90yvgj0qswlwpunel94mkh04a
CGI
0
1609
205805
204327
2022-07-25T00:19:50Z
はいかぐら
45848
/* コード例 */
wikitext
text/x-wiki
<small>{{Pathnav|メインページ|工学|情報技術|プログラミング}}</small>
{{Wikipedia|Common Gateway Interface}}
{{Otheruses|CGIの仕組み|[[Perl]]におけるCGIプログラミング|Perl/CGI}}
'''CGI'''(シージーアイ、'''''C'''ommon '''G'''ateway '''I'''nterface'')とは、[[w:Webサーバ|ウェブサーバ]]が独立した外部プロセス(CGIプログラム)で[[w:ウェブページ|ウェブページ]]を生成できるようにする仕組みです。CGIプログラムの記述には[[Perl]]などの[[w:スクリプト言語|スクリプト言語]]がよく用いられますが、基本的に[[w:標準ストリーム|標準入出力]]を備えている[[w:プログラミング言語|プログラミング言語]]であれば(たとえば[[C言語]]や[[シェルとシェルスクリプト|シェルスクリプト]]でも)CGIプログラムを記述することは可能です。
== 概要 ==
ウェブサーバのApacheは、(世間一般でサーバ向けプログラム言語と言われている)PHPやPerlのコードだけでなく、C言語をコンパイルしたバイナリファイルも実行できます(ただし、バイナリなので、ホストアーキテクチャごとにコンパイルしなおす必要があるので、取り回しが悪いので、用途は例外的に処理速度が極端に必要な場合以外には、めったにC言語バイナリの読み取りは用いられない)。
広い意味での『CGI』の「プログラミング言語の内容を実行する」との意味は、具体的にはウェブページでユーザからの入力に応答したり、動的な出力を行ったりするための機構などもCGIです。CGIの規格はhttp://hoohoo.ncsa.uiuc.edu/cgi/interface.html(インターネットアーカイブ: https://web.archive.org/web/20070809114039/hoohoo.ncsa.uiuc.edu/cgi/interface.html )で定められています。ここで'''動的'''とはたとえば、ブラウザからリクエストを受け付けた日時をページとして表示させるものも動的なページの一つです。[[w:ウィキ|ウィキ]]や[[w:ブログ|ブログ]]なども動的なページに含まれます。これに対して'''静的'''とはあらかじめ用意してある[[HTML]]等で記述されたドキュメントをリクエストへの応答時に変更を行わずに配信することを指しています。
PerlやPHPなど用いている言語が何かかは別として、現在インターネット上で大規模、あるいは著名なウェブサイトのほとんどは何らかの動的な仕組みを有していると考えられます。CGIの仕組みを理解することは大規模なデータをインターネット上で出版する技術的な背景を学ぶのと強い関係があると言えます。
CGIが行う動的な作用は主に以下の4要素によって成り立っています。
* [[w:標準ストリーム|標準入力・標準出力]] ・ [[w:コマンド (コンピュータ)| コマンドライン]] [[w:引数|引数]] (コマンドライン引数)
* [[w:環境変数|環境変数]]
* [[w:Hypertext Transfer Protocol|HTTP]] エラーが来る場合があります。 [[w:HTTPステータスコード|HTTPステータスコード]]
* HTMLの[[w:フォーム (ウェブ)| FORM]] [[w:HTML要素|要素]]
ウェブサーバで動的にコンテンツを生成する仕組みには他に、ウェブサーバのモジュール(mod_perlなど)やFastCGIがあります。
これらのCGIと大きな違いは、CGIの「リクエストごとに新しくプリオセスを生成する」という負荷の大きな処理を、ウェブサーバプロセス内で実行したり、常駐するプロセスとウェブサーバの間での通信を行うことでサケている点です。
== C言語でCGI ==
ApacheはCGIを実行するためには {{code|htttpd.conf}} の書換えの必要があります。
XAMPPであれば、場所は、\xampp\apache\conf の中に設定ファイル
:「http.conf」
があるので、探して httpd.conf のファイルの中身の下記のような部分を、下記のようになるように書換えます。
多くのGNU/Linuxのディストリビューションでは、 /etc/httpd/conf に httpd.conf があります。
/etc/httpd.conf の所有者は root もしくは www なので、{{code|sudo vi /etc/httpd.conf}} などとし書込み保護した状態を維持してください。
<div style="border:red 3px double">過去の編集で、'''httpd.conf の所有者をログイン可能ユーザに変更することを指図する記述'''がありましたが、重大なセキュリティホールとなるので、もしその記載の通りに設定してしまった方がいたら、/etc/httpd.conf の所有者を root に戻し、所有者以外に書込みパーミッションを与えていないか確認ください。</div>
=== CGI使用設定の方法 ===
設定の方法は2種類あります。
==== <code> <Directory /> </code> タグの内容を書き換える方法 ====
'''書き換え前'''
<SyntaxHighlight lang="apache">
<Directory />
AllowOverride none
Require all denied
</Directory>
</SyntaxHighlight>
'''書き換え後'''
* AllowOverride のあとを none から ALL に書き換える。
* Optionsのあとを「ExecCGI」に書き換える。
<SyntaxHighlight lang="apache">
<Directory "C:/xampp/cgi-bin">
AllowOverride All
Options ExecCGI
Require all granted
</Directory>
</SyntaxHighlight>
==== ScriptAlias を書き換える方法 ====
ScriptAlias という行を、下記のようになるように、書き換えます。
<SyntaxHighlight lang="apache">
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</SyntaxHighlight>
どちらの方法で編集するにしても、もしApacheをすでに立ち上げていたら、いったんApacheを終了してから、再度、立ち上げ癒し手下さい。
Apacheの起動時に設定ファイルを読み込む方式のようなので、立ち上げ直さないと、設定が反映されない場合があります。
Apacheを終了させるには、コマンド
<SyntaxHighlight lang="bash">
sudo service httpd stop
</SyntaxHighlight>
でApacheが終了します。
右上のXボタンを押してコマンドラインなどのウィンドウを閉じるだけでは、Apacheが終了しない場合が普通なので、終了させるためにはコマンド入力で確実に、いったんApacheを終了させてください。
Apacheを立ち上げるには、コマンド
<SyntaxHighlight lang="bash">
sudo service httpd start
</SyntaxHighlight>
で立ち上がります。
=== 次の作業 ===
今後の作業の暗黙の前提として、Apacheサーバーを立ち上げるのを忘れないように(よく忘れてエラーになる)。さっさと先にApacheサーバを立ち上げよう。
さて、たとえば、下記のようなC言語ファイルをテキストファイル(『メモ帳』で良い)に書いて、コンパイル(gccでも良い)して、実行ファイル(windowsならexeファイル)にしよう。
'''コード例'''
<syntaxhighlight lang="C">
#include <stdio.h>
int main(void) {
printf("Content-Type: text/html\r\n\r\n");
int a = 3, b = 4;
int c = a + b;
printf("sum %d\n", c);
return 0;
}
</syntaxhighlight>
<code>Content-Type: text/html</code>
というのは、Apache側が解釈のために必要な情報であり、これから送られてくるprintf文の内容が、テキストファイルまたはHTMLファイルであることを宣言しているテキスト文です。「HTMLヘッダ」などと言われる、webでの情報のやりとりをする際の、送受信メッセージ文の一種です。
さて、Windows版ApacheであるXAMPPの場合、上記コード例をコンパイルして出来上がった実行ファイル(ファイル名を指定しなければWindows版gccなら「 a.exe 」という名前になる)を、
フォルダ
\xampp\cgi-bin
に入れればいい。
GNU/Linux版の素のApacheの場合、フォルダ cgi-bin の場所は
/var/www
ですので、そこにa.outなどの実行ファイルをいれればすみます。ですが、初期設定では、root所有になってますので、chownコマンドで所有者を変えてください。
sudo chown ログインユーザ名 /var/www/cgi-bin
とにかく、cgi-bin フォルダにバイナリファイルを入れたら、のあと単にwebブラウザで
http://localhost/cgi-bin/a.exe
にアクセスすればいい。
または実行ファイル名がa.exe以外の別のファイル名なら、
http://localhost/cgi-bin/実行ファイル名
にアクセスすればいい。
すると、
上記コードの場合
sum 7
というふうに、webページでprintf文の内容が表示される。(GNU/Linux版Apacheでも同様の結果です。Fedora 32 で2020年7月14日に確認。)
C言語バイナリだろうが、Apache側がHTMLファイルを解釈してくれるので、なので、下記のようにprintf文中にHTMLタグを書いてバイナリ化しておけば、自動的にApacheがうまく変換して、ブラウザにHTMLタグの指示通りに表示できるようにしてくれる。
'''コード例'''
<syntaxhighlight lang="C">
#include <stdio.h>
int main(void) {
printf("Content-Type: Text/html\r\n\r\n");
int a = 3, b = 4;
int c = a + b;
printf("<h1>sum %d</h1>\n", c);
return 0;
}
</syntaxhighlight>
上記コードをコンパイルしたバイナリファイルをフォルダ cgi-bin に入れたあと、webブラウザでアクセスすると、大きな文字で、
<big>sum 7</big>
と表示される。
(GNU/Linuxでも同様の結果です。Fedora 32 で2020年7月14日に確認。)
== CGIそのものの実装方法 ==
もし、興味あるのがCGIを使ったサーバ公開ではなく、CGIそのものの機能を作りたい場合、そのためのCGIの原理の知識は色々と考えられますが、OSのコマンドラインに搭載されている
:標準出力のリダイレクト機能を使う方法
が、原理的と思われる方法です。(なお、理解のために方法を紹介しているだけであり、通常のサーバ構築ではCGI機能自体の新規の実装は不要な作業です。すでにApacheなどの既存のサーバソフトにCGI機能が搭載されているからです。)
また、コマンドプロンプトに実行させたいコマンド列をテキストファイルに記述して繰り返し使うことが出来ます。
Windowsならバッチファイル、UnixたUnixに類したOSならばシェルスクリプトと呼ばれます。
本科目では、リダイレクトについて説明します。バッチファイルの解説は別の科目にゆだねます。
=== Windowsの場合 ===
リダイレクトについては、Windowsの場合、DOSプロンプトで
<pre>
実行ファイル名 1> リダイレクト先のファイル名
</pre>
と入力すれば、標準出力に出される文字列がそのまま、リダイレクト先のファイルに書き込まれて保存されます。
たとえば実行ファイル名「hello.exe」で、リダイレクト先ファイル名「ridtest.txt」なら
<pre>
hello.exe 1> ridtest.txt
</pre>
というコマンドになります。
間の演算子の機能は、
:<code> 1> </code> だと実行ファイル成功時のリダイレクト、
:<code> 2> </code> だと実行ファイル失敗時のエラーメッセージのリダイレクト、
になります。
Apacheなどのウェブサーバは、指定されたCGI用のフォルダ内にある実行ファイルについては、すべてリダイレクトして実行すれば、それの出力文字列がテキストファイル(内容はHTMLファイルのこと)になりますので、あとは他のHTMLファイルと同様にリダイレクト先テキストファイルを読み取って表示すればいいだけです。
GNU/Linuxなど別OSでも、記法は違いますが、同様のリダイレクト機能があるので、それを使えばCGI機能が簡単に実装できるでしょう。
=== GNU/Linux の場合 ===
実行ファイルがカレント・ディレクトリにある場合、
ストリームを指定したリダイレクトのためのコマンドの書式は、
<pre>
./実行ファイル名 1> リダイレクト先のファイル名
</pre>
です。これで、リダイレクト先ファイルに、書き込まれます。
この書式は、sh ksh bash zsh に共通ですが csh とは異なります。
たとえば実行ファイル名 <code>hello</code> で、リダイレクト先ファイル名が <code>text.txt</code> なら
./hello 2> text.txt
/pre>
というコマンドになります。
なお、ストリーム番号の意味は
:<code> 1> </code> とすると標準出力のリダイレクト(ディフォルト)
:<code> 2> </code> とすると標準エラー出力のリダイレクト
になります。
== 開発の参考 ==
[[Perl/CGI]] のページも見てください。
[[Perl/ライブラリ・モジュールとオブジェクト指向]] のページもご覧ください。
[[w:テキストエディタ|テキストエディタ]] [[w:TeraPad|TeraPad]](テラパッド)等の[[w:テキストファイル|テキスト]](拡張子 <nowiki>*</nowiki>.txt)を <nowiki>*</nowiki>.cgi に変えた物です。書かれている内容はtextなのでコード指定はテキストエディタのファイルオープンでUTF-8に変えてから日本語が使えます。変えないと文字化けします。
* パソコンで初期の拡張子の表示を「表示する」にしないと、<nowiki>*</nowiki>.cgi.txt になってしまいます。名前付けは英字と数字しか使えません。Windowsの場合、コントロールパネルの検索で「拡張子」で設定してください。
動作が確認され ミスがないのが確認されたら、契約サーバーに[[w:アップロード|アップロード]]を[[w:FFFTP|FFFTP]]等でおこない、皆さんに楽しんでもらいましょう。属性(パーミッション)の変更もお忘れなく。
[[Perl/制御構造]]・[[Perl/リファレンス]]・[[Perl/はじめに]] もご覧ください。
[[w:とほほのWWW入門]]は、良い情報源になるかもしれません。
本書では[[w:Apache HTTP Server|Apache HTTP Server]]を用いた例を示しますが、ほかにも多くの[[w:Webサーバ|ウェブサーバ]]でCGIが利用可能です。
== Apache HTTP Server 2.2の組込み ==
* ファイル名は、以下指定なき物は「mihon.cgi」[[w:ディレクトリ|ディレクトリ]](フォルダー)はサーバーの場合なんでもよいですが「test-cgi」が無難かも知れません。
* [[w:ローカルサーバー|ローカルサーバー]]の場合、アパッチの指定されたフォルダーの中htdocsやcgi-binに「test-cgi」が無難かも知れません。「test-cgi」はウインドーズの場合、プロパティの書き換えなどの指定か互換性の変更が確か必要だったと思います。
* [[w:ローカルサーバー|ローカルサーバー]]の呼び出し実行は「<nowiki>http://127.0.0.1/test-cgi/mihon.cgi</nowiki>」とか「<nowiki>http://127.0.0.1/cgi-bin/test-cgi/mihon.cgi</nowiki>」をアドレスとして呼び出してください。
* 127.0.0.1はIPv4において[[w:localhost|localhost]]ローカルホストに当たるアドレスです。
* 契約サーバーは場所指定があったり、説明書きを読まないと分りません。『public_html 「test-cgi/mihon.cgi」』 など。
* アップしたら属性(パーミッション)を実行可能な700または755またはサーバー指定の値に変更します。
* ローカルの場合32bitと64bitのバージョンがあるので注意してください。また、アパッチの場合、conf の httpd.conf を書き換え、追加など必要だったと思います。これはインストールされたスタート内のプログラムからも出来ると思います。
** <strike>補足<br>これについてのホームページを見つけました。アドレス http://d.hatena.ne.jp/foussin/20110424/1303589811 分室の分室 443行目以下は、説明が分かってからの追加変更だと思います。最初に動かす時は触らない方がよいと思います。</strike>(リンク切れ)
** Statを押しても黒い箱が出てくる:ちょっと待ってください。Rrestatを押して再起動は出来ませんか?動いたをStopさせた後はRrestatで起動です。
*** Windowsでは通知領域「USB 抜差し等の▲の中」に入っています。
* Perl http://www.activestate.com/ の中の アクティブパル http://www.activestate.com/activeperl/downloads 自分のパソコンを選んでね。トップページは見てください。
* パールはPerl64の場合64を取ってPerlとして覚えて置いてください。パール → アパッチ の順でインストールしてください。
* 過去にウイルス対策ソフト「ノートン」において動作させられませんでしたが、現在は改善されているものと思われます。
* Perlリファレンスなど公開されているリファレンス(レファレンス(reference)とも言う) を組み合わせて一つのプログラムとして組み上げます。
* 不勉強の為、ウインドウズしか持って居ないのでそれしか分りません。詳しくは加筆お願いします。
PHPやPerlとは関係なく、一般に Apache の起動の方法は、GNU/Linux(Fedora32)の場合、ターミナル画面で、コマンド
sudo systemctl start httpd
です。(CentOS 7 以降はこうのようです。)
httpd とはlinuxの場合、Apache のことです。
なお、昔は
sudo service httpd start
というコマンドのようでした。
Apache が正常に動いているか確かめるには、ブラウザを開き、アドレスバーに
http://localhost
と入力します。
[[File:Apache Server 2.jpg|thumb|Apache ロゴマークの羽]]
バージョンにもよりますが、Apacheのロゴマークの羽の絵のあるwebページが表示されていれば、たぶんインストール成功しているでしょう。
Apache を終了するには、GNU/Linuxならターミナル端末で
systemctl stop httpd
で終了します。
昔は
service httpd stop
で終了でした。
終了後に先程の localhost のリンク先に移動しても、何も読み込みできないハズです。(Apacheを終了したので、読み込みできないのが成功。)
そもそもアパッチをどうインストールすればいいかについては、たとえば『[[PHP/確実に動作させるまで]]』などに解説がある。(2020年4月21日の時点では、まだ Apache 専用のページはWikibooks日本語版には無い。)
GNU/Linux の CentOS系の場合、フォルダ階層 <code> var/www/html </code> に、目的のhtmlファイルを入れる。(なお、このようなフォルダ(そこにhtmlなどを入れるとサーバーが公開してくれる場所)のことをドキュメントルート DocumentRoot という。)
あらかじめ、目的のhtmlファイルを作っておく。
たとえば、serverTest.html というファイルが作ってあり、このhtmlファイルを公開したい場合、
まず、
sudo cp serverTest.html /var/www/html
というコマンドになる。
SE Linux がオンだと設定が面倒なので、
sudo setenforce 0
でSE Linuxをオフできる。
webブラウザで <code> http://localhost/serverTest.html </code> にアクセスして、作成したhtmlどおりの内容が表示されれば、ここまでは成功。(外部公開するには、まだ作業が続く。)
ファイル名の部分(例では末尾の serverTest.html )は、作成したhtmlファイルのファイル名にする。
webブラウザで確認し終わったら
sudo setenforce 1
でSElinuxの設定をオンに戻す。
== Perl/CGIプログラムの例 ==
PerlでCGIプログラムをする場合、
perlだけでなく perl-CGI もインストールする必要があります。
GNU/Linux の Fedoraの場合、
sudo dnf install perl perl-CGI
で両方とも入ります。sudo dnf install perl だけでは、perl-CGI がインストールされません。
Fedoraにインストールする場合、dnf コマンドでの perl-CGIの末尾3文字の「CGI」は大文字でなければなりません。(でないとダウンローダが認識しないです。)
=== コード例 ===
下記のコードは、Perlによる単純なCGIプログラムの例です。CGIプログラムは、後述の設定をしたあとにwebブラウザで閲覧して確認できます。(コマンド端末では確認できないか、著しく確認が困難。)
;コード例
<syntaxhighlight lang="Perl">
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "Hello World!\n";
</syntaxhighlight>
::(2020年6月2日に Fedora 32 でブラウザ上(Firefox 76)での動作を確認ずみ。ただし後述の追加設定が必要。)
text/htmlのあとのエスケープシーケンスは必ず2つ \n\n としてください。もし1つだけだと、ブラウザで見てもエラーになり、「Hello World!」が表示されません。(もし \n が 1つだけだと「500 Internal Server Error」になります。)
;解説
* シュバング行(''shebang'')
#!/usr/bin/perl
というのは何かというと、これはシュバング行というOSの機能で、インタプリタに何を使うかを指定します。
書式はコメント文と同様に「#」から始まってますが、しかしコメントではないので、消さないでください。消すと動作しなくなります(インタプリタの実行用バイナリの場所が不明になるので、実行できなくなるので)。
PerlだけでなくUnix系のシェルスクリプトなど他のプログラム言語でも同様にシュバング行を記述する事があります。(詳しくはシェルスクリプトなどの教科書を参照せよ。)
* shebang は、必ずファイルの1行目になければいけません
* HTTPヘッダ
Content-Type: text/html
というのは何かというと、HTTPヘッダというものです。実はwebブラウザなどのwebアプリケーションでは、HTMLの情報とは別に、先に、これから送受信しようとする情報の種類などの打ち合わせのために HTTPヘッダ というものを送受信しあってます。(Perlの場合は「CGIヘッダ」ともいいますが、C言語やPHPなど他の言語では「HTTPヘッダ」というので、本wikiではHTTPヘッダで統一します。)
そのHTTPヘッダで送受信しあう情報のひとつに「Content-Type: 」という種類が存在し、「Content-Type: text/html」という文章によって「これからテキストファイルまたはHTMLファイルを送る」と相手先に伝えています。
HTTPサーバーの仕様などで、そういう風に、先にHTTPヘッダをやりとりするというように、プロトコルなどが決まっているのです。(『ソケットプログラミング』などと言われる分野の書籍に、ここら辺のC言語プログラミング事情が書いてあったのだが、しかし2020年現在の出版市場では、市販のソケットプログラミングの書籍が無い出版状況なので、初心者は気にしなくてイイ。)
Apacheなどのサーバーソフトが気を利かせて、ファイル中に勝手に「print "Content-Type: 」みたいな文章を見つけたら、これはHTTPヘッダであるとして勝手に解釈してくれるという仕組みです。
その証拠に、コマンド端末(GNU/Linux の場合なら Terminal など)で上記コードを実行しても、単に
:※ コマンド端末での実行例
<pre>
Content-Type: text/html
Hello World!
</pre>
とそのままprint以下の文字を表示するだけです。コマンド端末で実行しても、けっして、webブラウザが起動したりはしないです。
なお、コマンド端末で実行するだけなら、シュバング行を消しても、コマンド端末上での実行だけなら可能です。(結果は print以下の文字が表示されるだけ。)
;コード例2
HTMLのソースコードを送りたい場合は、下記のように書きます。
<syntaxhighlight lang="Perl">
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "<!DOCTYPE html>\n";
print "<html>\n";
print "<head>\n";
print "<title>Example Web Page</title>\n";
print "</head>\n";
print "<body>\n";
print "<p>Hello, world!</p>\n";
print "</body>\n";
print "</html>\n";
</syntaxhighlight>
::(2020年5月17日に Fedora 32 でブラウザ上(Firefox 76)での動作を確認ずみ。ただし後述の追加設定が必要。)
しかし実用的には、下記のようにプログラムを書いたほうがラクでしょう。
;コード例3
<syntaxhighlight lang="Perl">
#!/usr/bin/perl
use strict;
use warnings;
print <<"EOT";
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<html>
<head>
<title>Example Web Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
EOT
</syntaxhighlight>
::(2020年5月17日に Fedora 32 でブラウザ上(Firefox 76)での動作を確認ずみ。ただし下記の追加設定が必要。)
;解説
use warnings; とは何かというと、これはプログラム中にエラーがあったら警告を出すという意味です。Perlはプログラム言語ですので、エラーも起こりえます。そのエラーの際に警告を出すという意味です。
ですが、これはコマンド端末で実行している場合のハナシです。
webブラウザで見ている場合、そのような気のきいた警告はしてくれないです。
また、use warnings; は警告をするだけですので、そのままプログラムを実行します。けっして、気をきかしてプログラム停止したりはしません。
use strict; は、プログラムの停止なども含めて、より厳格に判定および処置をします。
なので、実は上記プログラムから use warnings; および use strict; を除去しても、webブラウザ上で表示する事は可能です。
=== 必要な追加設定 ===
このファイルは、拡張子をかならず「.cgi」にしてください。(拡張子「.cgi」または「.pl」にしないと、今後の設定が面倒になります。)
このファイルを、フォルダ階層
/var/www/cgi-bin
の中に配置します。
もし cgi-bin フォルダがまだ作れていない場合、perl-CGIがまだインストールされてないと思われるので、まずperl-CGIをインストールしてください。
所有者がrootになってるなどで、配置できないなら
sudo chown ユーザー名 /var/www/cgi-bin
で所有者を変更できます。
冒頭の
#!/usr/bin/perl
の部分は、環境によっては
#!/usr/local/bin/perl
の場合もあります。
この部分 #!/usr/local/bin/perl は、perlのインタプリタを呼出してスクリプトを渡すための指示です。
これらperlインタプリタのバイナリの存在場所をさがすには、コマンド
which perl
で探せます。
;コマンド実行例
$ which perl
/usr/bin/perl
そして、制作したサンプルファイルは、アクセス権の設定で「プログラムとして実行可能」にチェックボックスを入れてください。右クリックで現れるダイアログから設定できると思います。
インタープリターへのパスがわからない場合は、あるいは色々な環境で動かすことが想定される場合(本書もそのケースです)
#!/usr/bin/env perl
の様に POSIX でパスが決まっている env(1) を呼出し、(絶対パスでなく)コマンド名でインタープリターを指定します。
こうすると、env は環境変数PATHの中から順に インタープリター を探し、見つかったインタープリターにスクリプトを渡し起動します。
----
しかし、サーバがApacheの場合、まだ、これだけでは動きません。
Apacheは初期設定では、cgiスクリプトを動かさない設定になっています。なので、まず、この初期設定を書き換える必要があります。
cgiスクリプトを動かせるように設定を変更するために、設定ファイルの httpd.conf というファイルを書き換えて、
AddHandler cgi-script .cgi
という文章を追加する必要があります。
なお、通常のapacheでは、すでにコメントアウトされた状態で
#AddHandler cgi-script .cgi
とあるので、単に冒頭のコメントアウト記号#をはずせばいいだけです。
この書き換えにより、拡張子 .cgi のあるファイルを、cgiスクリプトとして処理できるようになります。
なお、perlなどで使われる拡張子 「.pl」のファイルもCGIスクリプトとして実行したいなら、上記の AddHandler に
#AddHandler cgi-script .cgi .pl
と「.pl」を追加するだけで済みます。
ただし、管理者が通常では root になっているので、そのままでは、書き換えできません。なのでGNU/Linuxの場合、コマンドで
sudo chown ログインユーザ名 /etc/httpd/conf/httpd.conf
で、管理者を変えてから、管理者設定を書き換えることになります。
書き換えが終わったら、apache を立ち上げ直します。
そして、webブラウザで
http://localhost/cgi-bin/ファイル名.cgi
にアクセスしてください。
;実行結果
ブラウザ画面上に
Hello, world!
と表示されている。また、そのページのタイトルとして、タブ欄などに「Example Web Page」と書いてある。
=== HTMLとの連動の例 ===
では、より実用的なプログラムを見ていきましょう。
下記のプログラムは、入力した文字列を、htmlのフォーム機能を使って別ファイル(例では catchtest.cgi ) に送るプログラムです。
;コード例:<syntaxhighlight lang="Perl">
#!/usr/bin/env perl
print <<"EOT";
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<form action="catchTest.cgi" method="post">
ユーザー名を登録: <input type="text" name="username">
<input type="submit" value="登録">
</form>
EOT
</syntaxhighlight>
※ 『[[PHP/HTMLフォームからのデータ受け取り]]』と動作内容は同じです。
このように、パターンとして
<syntaxhighlight lang="Perl">
#!/usr/bin/env perl
print <<"EOT";
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
# ここに書きたいHTMLのソースコードを書く
# 中略
EOT
</syntaxhighlight>
というような書式で、単に <nowiki><!DOCTYPE html></nowiki> と <nowiki> EOT </nowiki> のあいだに、お決まりのパターンのコードを書くだけで、入出力機能のあるファームも簡単に作れます。
----
上記のコードの遷移先のページは、下記のようにつくります
;コード例
<syntaxhighlight lang="Perl">
#!/usr/bin/env perl
print "Content-type: text/html\n\n";
$msg = ""
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $msg, $ENV{'CONTENT_LENGTH'});
}
else {
$msg = $ENV{'QUERY_STRING'};
}
print " $msg と入力されました。";
</syntaxhighlight>
;実行結果
たとえば ggggggg とブラウザに表示された入力ボックスにしてボタン「登録」を押すと、
username=ggggggg と入力されました。
と表示される。
:(以上、実行結果)
;解説
まず、遷移先のページにも、シュバング行やHTTPヘッダを忘れないようにしましょう(無いとエラーになります(Internal Server Error など) )。
上記コードの if文 と else文 は、決まり文句です。 $msg以外はすべて、Perlでの決まり文句です。STDINは標準入力のことです。
Perlでは、formタグからのPOSTの受け取りは、標準入力 STDIN を通して受け取りが行われる仕様です。
環境変数として REQUEST_METHOD や CONTENT_LENGTH や QUERY_STRING という環境変数があらかじめ用意されています。なので上記コードでは、この変数はこのまま使う必要があります(勝手に名前を変えてはイケナイ)。
なお、環境変数を英語で environmental variable と言います。
if ($ENV{'REQUEST_METHOD'} eq "POST")
というのは、おおむね「もし環境変数 REQUEST_METHOD が POST なら」 のような意味です。
環境変数 REQUEST_METHOD には、フォームを呼び出した時のリクエストの結果がPOSTまたはGETのどちらかとして入っています。
{| class="wikitable" style="float: right;"
|+ 等価演算子
|-
! style="text-align: center;" | 数値として評価
! style="text-align:center" | 文字として評価
! 意味
|-
| ==
| style="text-align:center"| eq
|等しい場合に真
|-
| !=
| style="text-align:center"| ne
|等しくない場合に真
|-
|}
eq 演算子は、「eqの左右の両辺をもし文字列とした場合に、両辺が等しいか?」を調べる演算子です。
いっぽう、<nowiki>==</nowiki> 演算子は、両辺を数値とした場合に等しいかを調べる演算子です。(C言語と違って、Perlでは変数の宣言時に型指定が無いので、条件分岐if文では、こういった演算子の区別が必要になる。)
なので、けっして eq演算子の部分を <nowiki>==</nowiki> 演算子に変えてはダメです。
なお、両辺が等しくない場合については、文字として評価する場合には ne 演算子、数値として評価する場合には != 演算子 です。
さて、表示結果の username というのは単に、勝手につけたオブジェクト名であり、呼び出し元のファイルのHTMLタグで勝手に命名したオブジェクト名ですので、もしそのオブジェクト名が変われば、表示結果の左辺のこの部分は名前になります。
結局
オブジェクト名 = 受け取った内容
のように、オブジェクト名と一緒に、Perlでは POST で受け取った内容を管理する仕組みです。
=== 高度な例 ===
より高度なCGIプログラムは次のようになります。
<syntaxhighlight lang="Perl">
#!/usr/local/bin/perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
print $q->header( -charset => "UTF-8" );
print $q->start_html( -title => "Example Web Page" );
print $q->p("Hello, world!");
print $q->end_html;
</syntaxhighlight>
上記の書き方は「信じられない植物 ダウンロード」で検索して、参考に見てください。CGIのゲームです。
ちょっと古い見なれた構文 オリジナルです。printは一般的に使われています。
<syntaxhighlight lang="Perl">
#!C:/Perl/bin/perl
#上は必ず一行目に書いてローカルホスト C:\Perl\bin\perl.exeを使うと言う定義です。コメントも書けません。
print "Content-type:text/html\n\n"; #\n改行がふたつ必要ですクッキーは上に書きます。
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>てすと</title>
</head>
<BODY BGCOLOR="#ffffff">
<h1>test</h1>
EOF
print "動くかな。<br>\n"; #print に続く物がプログラムです。ヘッダーとフッタに分割してサブルーチンとする事もできます。
print <<"EOF" ;
</BODY>
</html>
EOF
exit;
__END__
</syntaxhighlight>
*編集者の経験により意見が入るかも知れません。自論を押し付ける気はありません。
* cgi-lib.pl(著作権ありと言うものがありデコードさせたり、ヘッダーやフッタを書き出すには便利ですが、融通が利かないという難点があります。
*最近、CSSを使う事が多くなりましたが、対応状況が判りません。
*JavaScriptもあったり、ヘッダーの可視性が不十分です。
* [https://ja.wikipedia.org/wiki/Jcode.pl jcode.pl](著作権あり)もよく見かけますが書いた言語と同じ言語が通常戻ってきます。メール用[https://ja.wikipedia.org/wiki/Sendmail Sendmail]の[https://ja.wikipedia.org/wiki/JIS%E6%BC%A2%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89 JISコード]に変換させるには非常に便利ですがcgiからメールを送信しない場合は内部で言語変換させないのならば、あまり必要と思いません。
*では、デコードをどの様に組むか書いていきます。cgi-lib.pl(著作権あり)を使うと$in{'送られてきたデータ'}と返されますので$In{'送られてきたデータ'}と書き換えます。
<syntaxhighlight lang="Perl">
#!C:/Perl/bin/perl
#上記はサーバーで動かす時はサーバーの仕様書を見て変えてください。
#!/usr/local/bin/perl
# このcgiの名前
$this_cgi = "mihon.cgi";
# GETでの取り込みを禁止する。1 または 0
$getin = 0;
# ファイルのサイズ指定
$max_size = 100;
&decode;
&header;
&main;
&footer;
exit;
####### メイン処理 ######
sub main{
print 'あなたは ';
print "$In{'kakikomi'}";
print ' と書き込みしましたね。<br><br>'; # 全角空白は文字化けの為 ''を使って囲む。
print << "EOF" ;
<br>
<form action="$this_cgi" method="POST">
<input type="text" name="kakikomi" size="40" maxlength="30">
<input type="submit" value="送信する">
</form>
EOF
}
#######ヘッダー出力
sub header {
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>見本1</title>
</head>
<BODY BGCOLOR="#ffffff">
EOF
}
#デコード処理
sub decode {
my ($query,$pair);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
if ($query ne "" && $getin == 1){&err("GET");}
}
my ($saizu)=length $query;
if ($saizu > $max_size){&err("エラー・サイズオーバー");}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair);
# 文字のデコード
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$value =~ s/\0/0/g;
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/\r\n/<br>/g; #追加
$value =~ s/\r|\n/<br>/g;
$value =~ tr/+/ /;
$In{$key} = $value;
}
}
### フッタ #########
sub footer{
print "<br><br><table border='1'>";
print "<tr><th>フォーム要素名</th><th>データ</th></tr>";
foreach $key (keys %In) {
print "<tr><th>$key</th><td>$In{$key}</td></tr>\n";
}
print "</table><br>";
print <<"EOF" ;
</BODY>
</html>
EOF
exit;
}
###### エラー ########
sub err{
&header;
print 'エラー'."<br>\n";
print "$_[0]<br>\n";
&footer;
exit;
}
</syntaxhighlight>
== Perl/CGIプログラムの例2 ==
* 少し難しくなってきました。HTMLの知識、スタイルシートの組み込み、ジャバスクリプトの書き込みが追加になっています。
* ロックファイル、フォルダの好ましくない点を上げると、あっちもこっちもロックに来てロックがフル稼働になってしまうことです。
* つまり、ロックの分散化が必要になります。ファイルハンドルで別名を使うファイルによって付けてやれば、ファイルハンドルの衝突も起きないしファイルの衝突、待ち時間の軽減になると思います。
* これを踏まえた上で組んで見ました。
* ランダムもシードを与えなければタイムが自動的になります。
* ご要望があればもっと詳しく書きますが、とりあえずこんな物かと書き加えて試してみるのを目的に組みました。
<syntaxhighlight lang="Perl">
#!d:/Perl/bin/perl
#上記はサーバーで動かす時はサーバーの仕様書を見て変えてください。
# このcgiの名前
$this_cgi = "mihon.cgi";
# GETでの取り込みを禁止する。1 または 0
$getin = 0;
# ファイルのサイズ指定
$max_size = 100;
# カウンタファイル
$cntfile = './count.cgi';
# 無い時に自動的に作成する
unless(-e "$cntfile"){
open (FOUT, "> $cntfile") or &err("エラー・ファイルが作れません。");
close (FOUT);
chmod 0600,$cntfile;
}
#
# カウンタの桁数
$mini_fig = 6;
# 記録ファイルの名前
$datafile = './kiroku.cgi';
# 無い時に自動的に作成する
unless(-e "$datafile"){
open (FOUT, "> $datafile") or &err("エラー・ファイルが作れません。");
close (FOUT);
chmod 0600,$cntfile;
}
#
####--------------------------------------------------------
&decode;
&header;
&main;
&footer;
exit;
######### カウンタ処理
sub counter {
local($count,$cntup);
# カウントファイルを読みこみ
open(CUNT,"< $cntfile") || &err("Open Error: cntfile","in");
eval{flock(CUNT, 1);};
$count = <CUNT>;
close(CUNT);
local($local_time);
local($cnt,$kiroku_day,$keika_day,$today,$yestaday) = split(/<>/, $count);
$local_time = time + (9*60*60);#GMT+9:00補正
if (!$kiroku_day){
$kiroku_day = $local_time - ($local_time % (24*60*60));
}
if ($local_time - $kiroku_day > 24*60*60){
$keika_day += int(($local_time - $kiroku_day)/(24*60*60));
if ($local_time - $kiroku_day > 2*24*60*60){
$yestaday = 0;
}else{$yestaday = $today;}
$kiroku_day = $local_time - ($local_time % (24*60*60));
$today = 0;
}
$today++;
if (!$keika_day){$keika_day = 0; }
if (!$yestaday){$yestaday = 0; }
$cnt++;
open(CUNT,"> $cntfile") || &err("Write Error: cntfile","in");
eval{flock(CUNT, 2);};
print CUNT "$cnt<>$kiroku_day<>$keika_day<>$today<>$yestaday<>\n";
close(CUNT);
# 桁数調整
while(length($cnt) < $mini_fig) { $cnt = '0' . $cnt; }
#時間の整形
$date_sec = time;
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($date_sec);
# local($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($date_sec); # 日時を使えるように開放
local @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
local $m_week = $week[$wday];
$date = sprintf("%04d/%02d/%02d(%s) %02d:%02d:%02d",$year+1900,$mon+1,$mday,$week[$wday],$hour,$min,$sec);
print "<table border=\"0\">\n";
print "<tr><td rowspan=\"3\">\n";
print "<font size=\"6\"class=\"kazu\">$cnt</font><br>\n";
print "</td><td><font size=\"2\">経過</font></td><td><font size=\"2\">$keika_day</font></td></tr>\n";
print "<tr><td><font size=\"2\">今日</font></td><td><font size=\"2\">$today</font></td></tr>\n";
print "<tr><td><font size=\"2\">昨日</font></td><td><font size=\"2\">$yestaday</font></td></tr>\n";
print "<tr><td colspan=\"3\"><font size=\"2\"><form name=\"Watch0\"><input type=\"text\" name=\"watch01\" size=\"25\"></form></font></td></tr>\n";
print "</table><br>\n";
}
##### 記録遊び
sub asobkiroku {
$detskazu = int(rand(10))+1;
if(6 <= $detskazu){$asobimese = 'あなたの勝ち';}else{$asobimese = 'あなたの負け';}
open(DATS,"< $datafile") || &err("Open Error: datafile","in");
eval{flock(DATS, 1);};
@datas = <DATS>;
close(DATS);
unshift @datas,"$detskazu<>$asobimese<>$In{'kakikomi'}<>$date<>\n";
if(@datas > 10){$#datas = 9;}
open(DATS,"> $datafile") || &err("Write Error: datafile","in");
eval{flock(DATS, 2);};
print DATS @datas;
close(DATS);
foreach (@datas){
($b_detskazu,$b_asobimese,$b_kakikomi,$b_date) = split(/<>/);
if($b_detskazu >=6){
print "<font class=\"kachi\">$b_detskazu $b_asobimese コメント:$b_kakikomi $b_date</font><br>\n";
}else{
print "$b_detskazu $b_asobimese コメント:$b_kakikomi $b_date<br>\n";
}
}
}
####### メイン処理 ######
sub main{
&counter;
print 'あなたは ';
print "$In{'kakikomi'}";
print ' と書き込みしましたね。<br><br>'; # 全角空白は文字化けの為 ''を使って囲む。
&asobkiroku;
print << "EOF" ;
<br>
<form action="$this_cgi" method="POST">
<input type="text" name="kakikomi" size="40" maxlength="30">
<input type="submit" value="送信する">
</form>
EOF
}
#######ヘッダー出力
sub header {
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta tttp-equiv="Content-Script-Type" content="taxt/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>見本2</title>
<script language="JavaScript">
<!--
function DayWatch() {
var day = new Date();
if ( day.getYear() >= 2000 ){ var year = day.getYear() }
else { var year = day.getYear() +1900 }
var month = day.getMonth()+1;
var date = day.getDate();
if (month < 10) { //月.日が一桁の時頭に0を付ける処理
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
var time = new Date();
var hour = time.getHours();
var min = time.getMinutes();
var sec = time.getSeconds();
if (hour < 10) { //時・分・秒が1桁の時頭に0を付ける処理
hour = "0" + hour;
}
if (min < 10) {
min = "0" + min;
}
if (sec < 10) {
sec = "0" + sec;
}
document.Watch0.watch01.value = year +"/"+month+"/"+date+" "+hour+':'+min+':'+sec;
setTimeout("DayWatch()", 1000);
}
//-->
</script>
<style type="text/css">
<!--
.kazu{
color: #ff0000;
}
.kachi{
color: #0000ff;
}
-->
</style>
</head>
<BODY BGCOLOR="#ffffff" onLoad="DayWatch()">
EOF
}
#デコード処理
sub decode {
my ($query,$pair);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
if ($query ne "" && $getin == 1){&err("GET");}
}
my ($saizu)=length $query;
if ($saizu > $max_size){&err("エラー・サイズオーバー");}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair);
# 文字のデコード
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$value =~ s/\0/0/g;
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/\r\n/<br>/g; #追加
$value =~ s/\r|\n/<br>/g;
$value =~ tr/+/ /;
$In{$key} = $value;
}
}
### フッタ #########
sub footer{
print "<br><br><table border='1'>";
print "<tr><th>フォーム要素名</th><th>データ</th></tr>";
foreach $key (keys %In) {
print "<tr><th>$key</th><td>$In{$key}</td></tr>\n";
}
print "</table><br>";
print <<"EOF" ;
</BODY>
</html>
EOF
exit;
}
###### エラー ########
sub err{
if($_[1] ne "in"){
&header;
}
print 'エラー'."<br>\n";
print "$_[0]<br>\n";
&footer;
exit;
}
</syntaxhighlight>
* 下記のプログラムは一般的では無いかも知れませんがprint文で一気に書き出すのが楽ですし分りやすいです。 なので、モジュールは使用したくないのです。Perlでは、モジュール化して組み込む事も出来ます。
* 下記のプログラムは動的に動かすにはクッキーとソート「配列の中の第一変数を参照して」並べ替えを行っています。
* 分らない単語はここではプログラミングについての記述になるのでここでは触れません。リファレンスや事典を参照してください。
<syntaxhighlight lang="Perl">
#!d:/Perl/bin/perl
#上記はサーバーで動かす時はサーバーの仕様書を見て変えてください。
# このcgiの名前
$this_cgi = "mihon.cgi";
# GETでの取り込みを禁止する。1 または 0
$getin = 0;
# ファイルのサイズ指定
$max_size = 100;
# カウンタファイル
$cntfile = './count.cgi';
# 無い時に自動的に作成する
unless(-e "$cntfile"){
open (FOUT, "> $cntfile") or &err("エラー・ファイルが作れません。");
close (FOUT);
chmod 0600,$cntfile;
}
#
# カウンタの桁数
$mini_fig = 6;
# 記録ファイルの名前
$datafile = './kiroku.cgi';
# 無い時に自動的に作成する
unless(-e "$datafile"){
open (FOUT, "> $datafile") or &err("エラー・ファイルが作れません。");
close (FOUT);
chmod 0600,$cntfile;
}
#
# 登録するクッキーの名前
$COOKIE_NAME = 'mihon';
# クッキーの有効期間
$COOKIE_LIFE = 7;
#取り込みファイルの下準備通常は別ファイルとして作ります。
$require_txt = "errgo.cgi";
# 無い時に自動的に作成する
unless(-e "$require_txt"){
open (FOUT, "> $require_txt") or &err("エラー・ファイルが作れません。");
print FOUT "sub err_go { &err(\"エラークエストがありました。\");}\n1;\n"; #ファイルの終わりには「1;」が必要。出来たファイルを見てください。
close (FOUT);
chmod 0600,$require_txt;
}
####--------------------------------------------------------
require './errgo.cgi';
#sub err_go { &err("エラークエストがありました。");}
&decode;
&cookie_in;
if($In{'kakikomi'} eq "エラーゴー"){&err_go;} #エラーゴーと書かれた時エラーに行く。
&decode;
&cookie_in;
&header;
&main;
&footer;
exit;
######### カウンタ処理
sub counter {
local($count,$cntup);
# カウントファイルを読みこみ
open(CUNT,"< $cntfile") || &err("Open Error: cntfile","in");
eval{flock(CUNT, 1);};
$count = <CUNT>;
close(CUNT);
local($local_time);
local($cnt,$kiroku_day,$keika_day,$today,$yestaday) = split(/<>/, $count);
$local_time = time + (9*60*60);#GMT+9:00補正
if (!$kiroku_day){
$kiroku_day = $local_time - ($local_time % (24*60*60));
}
if ($local_time - $kiroku_day > 24*60*60){
$keika_day += int(($local_time - $kiroku_day)/(24*60*60));
if ($local_time - $kiroku_day > 2*24*60*60){
$yestaday = 0;
}else{$yestaday = $today;}
$kiroku_day = $local_time - ($local_time % (24*60*60));
$today = 0;
}
$today++;
if (!$keika_day){$keika_day = 0; }
if (!$yestaday){$yestaday = 0; }
$cnt++;
open(CUNT,"> $cntfile") || &err("Write Error: cntfile","in");
eval{flock(CUNT, 2);};
print CUNT "$cnt<>$kiroku_day<>$keika_day<>$today<>$yestaday<>\n";
close(CUNT);
# 桁数調整
while(length($cnt) < $mini_fig) { $cnt = '0' . $cnt; }
&dates;
print qq|<table border="0">\n|;
print qq|<tr><td rowspan="3">\n|;
print qq|<font size="6"class="kazu">$cnt</font><br>\n|;
print qq|</td><td><font size="2">経過</font></td><td><font size="2">$keika_day</font></td></tr>\n|;
print qq|<tr><td><font size="2">今日</font></td><td><font size="2">$today</font></td></tr>\n|;
print qq|<tr><td><font size="2">昨日</font></td><td><font size="2">$yestaday</font></td></tr>\n|;
print qq|<tr><td colspan="3"><font size="2"><form name="Watch0"><input type="text" name="watch01" size="25"></form></font></td></tr>\n|;
print qq|</table><br>\n|;
}
###### 日付と時間
sub dates {
#時間の整形
$date_sec = time;
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($date_sec);
# local($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($date_sec); # 日時を使えるように開放
local @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
local $m_week = $week[$wday];
$date = sprintf("%04d/%02d/%02d(%s) %02d:%02d:%02d",$year+1900,$mon+1,$mday,$week[$wday],$hour,$min,$sec);
}
##### 記録遊び
sub asobkiroku {
$detskazu = int(rand(10))+1;
if(6 <= $detskazu){$asobimese = 'あなたの勝ち';}else{$asobimese = 'あなたの負け';}
open(DATS,"< $datafile") || &err("Open Error: datafile","in");
eval{flock(DATS, 1);};
@datas = <DATS>;
close(DATS);
unshift @datas,"$detskazu<>$asobimese<>$In{'kakikomi'}<>$date<>\n";
if(@datas > 10){$#datas = 9;}
open(DATS,"> $datafile") || &err("Write Error: datafile","in");
eval{flock(DATS, 2);};
print DATS @datas;
close(DATS);
foreach (@datas){
($b_detskazu,$b_asobimese,$b_kakikomi,$b_date) = split(/<>/);
if($b_detskazu >=6){
print "<font class=\"kachi\">$b_detskazu $b_asobimese コメント:$b_kakikomi $b_date</font><br>\n";
}else{
print "$b_detskazu $b_asobimese コメント:$b_kakikomi $b_date<br>\n";
}
}
# 先頭の要素による並べ替え
@keys1 = map {(split /<>/)[0]} @datas;
@new_datas = @datas[sort {$keys1[$b] <=> $keys1[$a]} 0 .. $#keys1];
print "<br><br>\n";
foreach (@new_datas){
($b_detskazu,$b_asobimese,$b_kakikomi,$b_date) = split(/<>/);
if($b_detskazu >=6){
print "<font class=\"kachi\">$b_detskazu $b_asobimese コメント:$b_kakikomi $b_date</font><br>\n";
}else{
print "$b_detskazu $b_asobimese コメント:$b_kakikomi $b_date<br>\n";
}
}
print "<br><br>クッキーは $COOKIE{'kakikomi'} と $COOKIE{'date'} が表\示されます。<br><br>\n"; # 表は文字化けを起こすので\を入れます。
}
####### メイン処理 ######
sub main{
&counter;
print 'あなたは ';
print "$In{'kakikomi'}";
print ' と書き込みしましたね。<br><br>'."\n"; # 全角空白は文字化けの為 ''を使って囲む。
&asobkiroku;
print << "EOF" ;
<br>
<form action="$this_cgi" method="POST">
<input type="text" name="kakikomi" size="40" maxlength="30">
<input type="submit" value="送信する">
</form>
EOF
}
### クッキーに値をセット ####
sub set_cookie{
if ($In{'kakikomi'}){ #書込の時限定。
# if (!$In{'coodel'}){
&dates; # 日付と時間のサブルーチン
$COOKIE{'kakikomi'} = $In{'kakikomi'};
$COOKIE{'date'} = $date;
# }
}
}
### クッキー読み出し ######
sub cookie_in{
my ($pair, $cpair);
foreach $pair (split(/;\s*/, $ENV{'HTTP_COOKIE'})) {
my ($name, $value) = split(/=/, $pair);
# 単一のクッキー値から%COOKIEにデコード
if($name eq $COOKIE_NAME) {
foreach $cpair (split(/&/, $value)) {
my ($cname, $cvalue) = split(/#/, $cpair);
$cvalue =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$COOKIE{$cname} = $cvalue;
}
last;
}
}
}
### クッキー発行 ####
sub cooki_hakkou{
&set_cookie; # クッキーのセット
my (@cpairs, $cname, $cvalue, $value);
if ($In{'coodel'}){$COOKIE_LIFE = -1;} # クッキー消去
# %COOKIEを単一のクッキー値にエンコード
foreach $cname (keys %COOKIE) {
$cvalue = $COOKIE{$cname};
$cvalue =~ s/(\W)/sprintf("%%%02X", ord $1)/eg;
push @cpairs, "$cname#$cvalue";
}
$value = join('&', @cpairs);
# グリニッジ標準時の文字列
my @mon_str = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my @wdy_str = qw(Sun Mon Tue Wed Thu Fri Sat);
my $life = $COOKIE_LIFE * 24 * 60 * 60;
my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime(time + $life);
my $date = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
$wdy_str[$wday], $mday, $mon_str[$mon], $year + 1900, $hour, $min, $sec);
return ("Set-Cookie: $COOKIE_NAME=$value; expires=$date\n");
}
#######ヘッダー出力
sub header {
($my_cookie) = &cooki_hakkou;
print "$my_cookie";
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta tttp-equiv="Content-Script-Type" content="taxt/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>見本2</title>
<script language="JavaScript">
<!--
function DayWatch() {
var day = new Date();
if ( day.getYear() >= 2000 ){ var year = day.getYear() }
else { var year = day.getYear() +1900 }
var month = day.getMonth()+1;
var date = day.getDate();
if (month < 10) { //月.日が一桁の時頭に0を付ける処理
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
var time = new Date();
var hour = time.getHours();
var min = time.getMinutes();
var sec = time.getSeconds();
if (hour < 10) { //時・分・秒が1桁の時頭に0を付ける処理
hour = "0" + hour;
}
if (min < 10) {
min = "0" + min;
}
if (sec < 10) {
sec = "0" + sec;
}
document.Watch0.watch01.value = year +"/"+month+"/"+date+" "+hour+':'+min+':'+sec;
setTimeout("DayWatch()", 1000);
}
//-->
</script>
<style type="text/css">
<!--
.kazu{
color: #ff0000;
}
.kachi{
color: #0000ff;
}
-->
</style>
</head>
<BODY BGCOLOR="#ffffff" onLoad="DayWatch()">
EOF
}
#デコード処理
sub decode {
my ($query,$pair);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
if ($query ne "" && $getin == 1){&err("GET");}
}
my ($saizu)=length $query;
if ($saizu > $max_size){&err("エラー・サイズオーバー");}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair);
# 文字のデコード
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$value =~ s/\0/0/g;
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/\r\n/<br>/g; #追加
$value =~ s/\r|\n/<br>/g;
$value =~ tr/+/ /;
$In{$key} = $value;
}
}
### フッタ #########
sub footer{
print "<br><br><table border='1'>";
print "<tr><th>フォーム要素名</th><th>データ</th></tr>";
foreach $key (keys %In) {
print "<tr><th>$key</th><td>$In{$key}</td></tr>\n";
}
print "</table><br>";
#------- クッキー要素名 ---------
my ($name, $value);
print "<table border='1'>";
print "<tr><th>クッキー要素名</th><th>データ</th></tr>";
while (($name, $value) = each(%COOKIE)) {
print "<tr><td>$name</td><td>$value</td></tr>\n";#\\n
}
print "</table><br>";
print <<"EOF" ;
</BODY>
</html>
EOF
exit;
}
###### エラー ########
sub err{
if($_[1] ne "in"){
&header;
}
print 'エラー'."<br>\n";
print "$_[0]<br>\n";
&footer;
exit;
}
</syntaxhighlight>
==サーバー攻撃の防御==
*アクセスポイントの環境変数を用いてプログラムを守るものです。
*設置は出来るだけ上の方に書いた方が良いと思います。
<syntaxhighlight lang="Perl">
#!D:/Perl/bin/perl
#!/usr/local/bin/perl
#このプログラム名
# in_atakka.cgi
#作成されるファイル atakka.cgi
&in_atakka;
sub in_atakka {
local($c_tim,@tem_atakku,$i,$ma_aru,@tem_atakku_new,$ma_addr,$ma_host,$ma_tim,$ma_kaisu,@new_atakku_new,$count11);
my $get_host = $ENV{'REMOTE_HOST'};
my $get_addr = $ENV{'REMOTE_ADDR'};
if ($get_host eq "" || $get_host eq $get_addr) {
$get_host = gethostbyaddr(pack("C4", split(/\./, $get_addr)), 2) || $get_addr;
}
$c_tim = time;
if(!(-e "atakka.cgi")){
open(AT,"> atakka.cgi") || &disp;
close(AT);
}
open(AT,"< atakka.cgi") || &disp;
eval{ flock (AT, 1); };
@tem_atakku = <AT>;
close(AT);
$i=0;
$ma_aru =0;
@tem_atakku_new = (@tem_atakku);
foreach (@tem_atakku){
($ma_addr,$ma_host,$ma_tim,$ma_kaisu) = split(/<>/);
if($ma_addr eq $get_addr && $get_host eq $ma_host && $ma_kaisu > 5){
if($ma_tim + 600 < $c_tim){$ma_kaisu = 0;}else{&disp;}
}
if(!($ma_addr eq $get_addr && $get_host eq $ma_host) && $ma_kaisu > 5){ #5
$i++;
next;
}
if($get_addr eq $ma_addr && $get_host eq $ma_host && $c_tim < $ma_tim + 2){
$ma_kaisu++;
$tem_atakku_new[$i] = "$get_addr<>$get_host<>$c_tim<>$ma_kaisu<>\n";
$ma_aru =1;
last;
}else{
$ma_aru =0;
$ma_kaisu = 0;
unless($#tem_atakku_new < 0 && $ma_kaisu > 5){splice(@tem_atakku_new,$i,1);}
last;
}
$i++;
}
foreach (@tem_atakku_new){
($ma_addr,$ma_host,$ma_tim,$ma_kaisu) = split(/<>/);
if($c_tim > $ma_tim + 600){next;} #経過済みのタイムアウト者を消す。10分
if(@tem_atakku_new > 3 && $c_tim > $ma_tim + 3 && $ma_kaisu <= 2){ #30以上の参加者で3秒以上経過して2回以下なら消すtest 3
next;
}
push @new_atakku_new,"$_";
}
@tem_atakku_new = (@new_atakku_new);
if(!$ma_aru){
if(@tem_atakku_new > 5){&disp("アクセスが多いのでお待ちください。");} #50以上の参加者の時は新規に入るのを待ってもらう。test 5
push @tem_atakku_new,"$get_addr<>$get_host<>$c_tim<>1<>\n";
}
if(@tem_atakku_new == 0){&disp("exit");}
open(AT,"> atakka.cgi") || &disp("Fail");
eval{ flock (AT, 2); };
$count11 = 0;
foreach (@tem_atakku_new){
if(m/$get_host+/){$count11 = 1;}
}
if(!$count11){close(AT);&disp("exit2");}
print AT @tem_atakku_new;
close(AT);
if(-z "atakka.cgi"){&disp("Fail=0");}
}
sub disp{
print "Content-type:text/html; charset=UTF-8\n\n";
print <<"EOF";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>エラー</TITLE>
</HEAD>
<BODY>
<h1>過負荷によるエラーが起こりました。</h1>
$_[0]<br>
<h2>10分ほど経ったらもう一度試してみてください。</h2>
<Script Language="JavaScript">
<!--
alert("10分ほど経ったらもう一度試してみてください。");
// End -->
</Script>
<br><br>
</BODY>
</html>
EOF
exit;
}
####本文
local(@tem_atakku_new,$prit_out,$ma_addr,$ma_host,$ma_tim,$ma_kaisu);
open(AT,"< atakka.cgi") || &disp;
eval{ flock (AT, 1); };
@tem_atakku_new = <AT>;
close(AT);
foreach (@tem_atakku_new){
($ma_addr,$ma_host,$ma_tim,$ma_kaisu) = split(/<>/);
$prit_out .= "($ma_addr,$ma_host,$ma_tim,$ma_kaisu)<br>\n";
}
print "Content-type:text/html; charset=UTF-8\n\n";
print <<"EOF";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>アタックチェック</TITLE>
</HEAD>
<BODY>
<h1>ファイル内容確認</h1>
$prit_out
<br><br><br><br><br><br><br><br><br><br><br><br>
</BODY>
</html>
EOF
exit;
</syntaxhighlight>
==IPで管理者識別==
*自分の今のIPを登録識別する事で不正アクセスをしにくくする。
*ディレクトリと2つのプログラムによる共有データを使う。
<syntaxhighlight lang="Perl">
main.cgi 実行ファイル
フォルダー host3 を作ってください。
host.cgi 実行ファイル
in_host.cgi 空ファイル
host_koushin_ari.txt 空ファイル
##################### main.cgi #####################
#!D:/Perl/bin/perl
# サーバーに合わせて下さい
#!/usr/local/bin/perl
#!C:/Perl/bin/perl
# このファイルの名前
$this_cgi = "main.cgi";
# データー量
$max_size = 500;
# get禁止 1
$getin =1;
# 入口で強化するか
$host_kyuka = 'yes';
# 許可管理者名
$ohna_name = 'ウィキブックス';
# オーナーパスの設定(変更してください)
$ohna_pas = '0000';
# 管理者IPの簡易登録の合言葉
$aikotoba = 'wikibooks';
# ホスト管理用専用cgi
$host_cgi = "./host3/host.cgi";
# ホストのファイル
$in_host = "./host3/in_host.cgi";
# ホスト変更・追加などの報告
$koshin_fail = './host3/host_koushin_ari.txt';
# 記録しておくIPの数 1個多くなります。0の時1個
$ip_kazu = 5;
##########################
&decode;
if($In{'mode'} eq 'nyuryoku'){&nyuryoku;}
if($In{'mode'} eq 'admin'){&admin;}
&syoki;
exit;
######
sub syoki {
&acsesu;
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>メイン</title>
</head>
<BODY BGCOLOR="#ffffff">
<br>
<form action="$this_cgi" method="POST">
<input type="hidden" name="mode" value="nyuryoku">
<input type="submit" value="管理室入り口へ"><br>
</form>
<form action="$host_cgi" method="POST">
<input type="submit" value="ホスト管理明細"><br>
</form>
<br><br>
$host_mes
<br><br>
EOF
if ($ohna_name eq $In{'kanrisya_name'} && $ohna_pas && $ohna_pas eq $In{'kanrisya_pas'}){ #管理者のみ表示
if(-e "$koshin_fail"){
open (FIN, "$koshin_fail") or &err("エラー・ファイルが開けません..koshin_fail");
eval{ flock (FIN, 1); };
$tem_atakku = <FIN>;
close(FIN);
($henkou_time,$mese1,$mese2) = split(/ /, $tem_atakku);
$now_time = time;
if($now_time > $henkou_time + 2*24*60*60){$mese1 = "";$mese2 = "";}else{print "$mese1 $mese2<br>\n";}
}
}else{
print "管理者不一致<br>\n";
}
print "<br><br><table border='1'>";
print "<tr><th>フォーム要素名</th><th>データ</th></tr>";
foreach $key (keys %In) {
print "<tr><th>$key</th><td>$In{$key}</td></tr>\n";
}
print "</table><br>";
print <<"EOF" ;
</BODY>
</html>
EOF
exit;
}
### アクセス管理 ##############
sub acsesu {
$host = $ENV{'REMOTE_HOST'};
$addr = $ENV{'REMOTE_ADDR'};
(@in_addr) = split(/\s/, $addr);
$addr = $in_addr[0];
$addr_in = $addr;
if ($host eq "" || $host eq $addr) {
$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr;
}
if ($host eq "") {$host = $addr;}
$host_in = $host;
if ($host_kyuka eq 'yes' && (-e "$in_host")){
if(!(-z "$in_host")){
open(IN,"< $in_host") || &err2("Open Error : in_host");
eval{ flock (IN, 1); };
$kanri_ip = <IN>;
close(IN);
chomp $kanri_ip;
(@m_ip) = split(/<>/,$kanri_ip);
$ok = 0;
foreach (@m_ip){
if($_ eq "$host_in $addr_in"){$ok = 1;last;}
}
if($_[0]){return ($ok);}
if(!$ok){
$ohna_pas = "";
$host_mes = "ホスト一致がありません。";
}else{
$host_mes = "ホスト一致があります。";
}
}
}
}
#デコード処理
sub decode {
my ($query,$pair);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
if ($query ne "" && $getin == 1){&err("GET");}
}
my ($saizu)=length $query;
if ($saizu > $max_size){&err("エラー・サイズオーバー");}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair);
# 文字のデコード
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$value =~ s/\0/0/g;
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/\r\n/<br>/g; #追加
$value =~ s/\r|\n/<br>/g;
$value =~ tr/+/ /;
$In{$key} = $value;
}
}
sub nyuryoku{
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>管理室入り口</title>
</head>
<BODY BGCOLOR="#ffff00">
<br>
<form action="$this_cgi" method="POST">
<input type="hidden" name="mode" value="admin">
<input type="text" name="kanrisya_name" value="" maxlength="30">名前<br>
<input type="text" name="kanrisya_pas" value="" maxlength="30">パスワード<br>
<input type="text" name="aikotoba" value="" maxlength="30">IP合言葉ホストが変更なしの場合書かなくてよい<br>
<input type="submit" value="送信">
</form>
</BODY>
</html>
EOF
exit;
}
#####
sub admin{
($okok) = &acsesu(1);
if(!($ohna_name eq $In{'kanrisya_name'} && $ohna_pas eq $In{'kanrisya_pas'})){return;}
if($aikotoba eq $In{'aikotoba'} && !$okok){
$host = $ENV{'REMOTE_HOST'};
($addr) = split(/ /, $ENV{'REMOTE_ADDR'});
if ($host eq "" || $host eq $addr) {
$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr;
}
if ($host eq "") { $host = $addr; }
open (IN, "< $in_host") or &err("エラー・ファイルが開けません in_host");
eval{ flock (IN, 1); };
$f_host = <IN>;
@host_kiroku = <IN>;
close (IN);
chomp $f_host;
(@f_in_host) = split(/<>/, $f_host);
$purasu = 0;
foreach $deta(@f_in_host){
if("$host $addr" eq $deta){$purasu = 1;}
push @new_f_in_host,$deta;
}
if(!$purasu){unshift @new_f_in_host,"$host $addr";}
if($#new_f_in_host > $ip_kazu){$#new_f_in_host = $ip_kazu;}
$new_f_host = join ("<>",@new_f_in_host);
$new_f_host .= "<>\n";
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time) ; #一括取り入れ
$year += 1900; # $year = $year + 1900 と同じ
++$mon ;
@youbi=('日','月','火','水','木','金','土');
$mond = sprintf("%02d",$mon);
$mdayd = sprintf("%02d",$mday);
$hourd = sprintf("%02d",$hour);
$mind = sprintf("%02d",$min);
$secd = sprintf("%02d",$sec);
$jikan = "$year年$mond月$mdayd日$youbi[$wday]曜日$hourd時$mind分$secd秒";
if($#host_kiroku >= 24){$#host_kiroku = 24;}
unshift @host_kiroku,"$host $addr<>$jikan<>$host<>$ENV{'REMOTE_HOST'}<>$addr<>$ENV{'REMOTE_ADDR'}<>\n";
open (OUT, "> $in_host") or &err("エラー・ファイルが開けません in_host");
eval{ flock (OUT, 2); };
print OUT $new_f_host;
print OUT @host_kiroku ;
close (OUT);
$ima_time = time;
open (FOUT, "> $koshin_fail") or &err("エラー・ファイルが開けません koshin_fail");
eval{ flock (FOUT, 2); };
print FOUT "$ima_time $host 許可ホストの変更がありました。";
close (FOUT);
}elsif(!$okok){return;}
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>管理室</title>
</head>
<BODY BGCOLOR="#00ffff">
<br>
<form action="$this_cgi" method="POST">
<input type="text" name="kanrisya_name" value="$In{'kanrisya_name'}" maxlength="30"><br>
<input type="text" name="kanrisya_pas" value="$In{'kanrisya_pas'}" maxlength="30"><br>
<input type="submit" value="トップページに値を持って帰る">
</form><br>
管理者の処理を行う場所です。
EOF
exit;
}
###### エラー ########
sub err{
if($_[1] ne "in"){
print "Content-type:text/html\n\n";
print <<"EOF" ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>エラー</title>
</head>
<BODY BGCOLOR="#ffffff">
EOF
}
print 'エラー'."<br>\n";
print "$_[0]<br>\n";
print <<"EOF" ;
</BODY>
</html>
EOF
exit;
}
####################### host3/host.cgi #########################
#!D:/Perl/bin/perl
# サーバーに合わせて下さい
#!/usr/local/bin/perl
#!C:/Perl64/bin/perl
##### 開発記録など ############
# ver1.01
#
# host.cgi 700(パーミッション)
##### 設定 ####################
# このcgiのファイルの名前
$this_cgi = 'host.cgi';
# オーナーパスの設定(変更してください)
$ona_pas = 'wiki';
# 許可管理者名
$kanre_name = 'ウィキブックス';
$ona_id = 'うぃきぺでぃあ';
$hozon_fail = 'in_host.cgi';
unless(-e $hozon_fail){
open (FIN, "> $hozon_fail") or &err2("エラー・ファイルが開けません.0");
close (FIN);
}
# 更新案内ファイル名
$koshin_fail = 'host_koushin_ari.txt';
# 記録しておくIPの数 1個多くなります。0の時1個
$ip_kazu = 5;
# get = 1 GET受け入れ禁止
$get_no = 1;
#=====================
&loadformdata; #フォーム入力
&getoin;
sub getoin{
print "Content-type:text/html;\n\n";
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>許可ホスト変更</title>
</head>
<body>
EOF
$host = $ENV{'REMOTE_HOST'};
($addr) = split(/ /, $ENV{'REMOTE_ADDR'});
if ($host eq "" || $host eq $addr) {
$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr;
}
if ($host eq "") { $host = $addr; }
$disp_ok = 0;
if($FORM{'name'} eq $kanre_name && $FORM{'id'} eq $ona_id && $FORM{'pas'} eq $ona_pas && $FORM{'kanri'} eq $FORM{'kensa'}){
open (IN, "< $hozon_fail") or die;
eval{ flock (IN, 1); };
$f_host = <IN>;
@host_kiroku = <IN>;
close (IN);
chomp $f_host;
(@f_in_host) = split(/<>/, $f_host);
$purasu = 0;
foreach $deta(@f_in_host){
$i = 0;$loop = 0;
foreach (0..$#f_in_host){
$d_no = "d_no$i";
if($FORM{$d_no} eq $deta){$loop = 1;}
$i++;
}
if(!$loop){
if("$FORM{'host_in'}" eq $deta){$purasu = 1;}
push @new_f_in_host,$deta;
}
}
if(!$purasu){unshift @new_f_in_host,"$FORM{'host_in'}";}
if($#new_f_in_host > $ip_kazu){$#new_f_in_host = $ip_kazu;}
$new_f_host = join ("<>",@new_f_in_host);
$new_f_host .= "<>\n";
&get_time;
if($#host_kiroku >= 24){$#host_kiroku = 24;}
unshift @host_kiroku,"$FORM{'host_in'}<>$jikan<>$host<>$ENV{'REMOTE_HOST'}<>$addr<>$ENV{'REMOTE_ADDR'}<>\n";
$host_in = $FORM{'host_in'};
open (OUT, "> $hozon_fail") or die;
eval{ flock (OUT, 2); };
print OUT $new_f_host;
print OUT @host_kiroku ;
close (OUT);
$ima_time = time;
open (FOUT, "> $koshin_fail") or die;
eval{ flock (FOUT, 2); };
print FOUT "$ima_time $host 許可ホストの変更がありました。";
close (FOUT);
$disp_ok = 1;
}
$kensa = sprintf("%04d",int(rand(10000)));
print <<EOF ;
<h2 align="center">許可ホスト変更</h2><br>
<div align="center">
host = $host<br>
addr = $ENV{'REMOTE_ADDR'}<br><br>
<form action="$this_cgi" method="post">
名前:<input type="text" name="name"><br>
ID:<input type="text" name="id"><br>
パスワード:<input type="password" name="pas"><br>
確認:<input type=text name="kensa"> <font color=#ff0000>$kensa</font>を左に入れてください
<input type=hidden name=kanri value=$kensa><br>
現在のホスト $host $addr<br>
設定ホスト:<input type=text name="host_in" value="$host $addr" size="50"><br>
<input type=submit value=" 送 信 "><br>
EOF
if($disp_ok == 1){
$i = 0;
foreach (@new_f_in_host){
print "<input type=\"checkbox\" name=\"d_no$i\" value=\"$_\">$_<br>\n";
$i++;
}
}
print <<EOF ;
</form>
EOF
foreach (@host_kiroku){
($host_disp0,$time_disp,$raitu_host,$addr_disp,$host_disp,$addr0_disp) = split(/<>/);
chomp $addr0_disp;
print "$host_disp0 , $time_disp : $raitu_host , $addr_disp , $host_disp , $addr0_disp<br>\n";
}
print "</div></body></html>\n";
exit;
}
### フォーム受信 ##########
sub loadformdata {
$max_size = 200;
my ($query,$pair);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
if ($get_no ==1 && $query ne ""){&err2("エラー・GET 禁止");}
}
my ($saizu)=length $query;
if ($saizu > $max_size){&err2("エラー・サイズオーバー");}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair);
# 文字のデコード
$value =~ tr/+/ /;
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$value =~ s/\0/0/g;
$value =~ s/&/&/g;
if($value =~ m/</ ){&err2("禁止コード < があります。");}
if($value =~ m/>/ ){&err2("禁止コード > があります。");}
$value =~ s/"/"/g;
$value =~ s/\x0D\x0A/<br>/g;
$value =~ s/\r|\n/<br>/g; #追加
$value =~ tr/\t//;
$FORM{$key} = $value;
}
(@kennsa) = split(/ /, $FORM{'host_in'});
if($kennsa[2]){&err2("コードの書き込み違反");}
}
### 現在の時間出し ###############
sub get_time{
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time) ; #一括取り入れ
$year += 1900; # $year = $year + 1900 と同じ
++$mon ;
@youbi=('日','月','火','水','木','金','土');
$mond = sprintf("%02d",$mon);
$mdayd = sprintf("%02d",$mday);
$hourd = sprintf("%02d",$hour);
$mind = sprintf("%02d",$min);
$secd = sprintf("%02d",$sec);
$jikan = "$year年$mond月$mdayd日$youbi[$wday]曜日$hourd時$mind分$secd秒";
}
sub err2{
print "Content-type:text/html;\n\n";
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>エラー</title>
</head>
<body>
<h2 align="center">$_[0]</h2><br>
</body></html>
EOF
exit;
}
</syntaxhighlight>
== 関連書籍 ==
* [[Perl]]
* [[PHP]]
* [[HTML]]
* [[CSS]]
* [[JavaScript]]
** [[JavaScript/XMLHttpRequest#Ajax|Ajax]]
[[Category:World Wide Web]]
[[Category:プログラミング言語]]
{{NDC|007.64}}
klytcv0z6mx7366u7c4rndna6zovbza
麻雀
0
3107
205836
198017
2022-07-25T10:00:26Z
はいかぐら
45848
wikitext
text/x-wiki
{{Pathnav|メインページ|ゲーム|frame=1}}
==前書==
麻雀とは中国伝来の'''ギャンブル'''である。雅やかな化粧の裏に隠しきれない猥雑さが非常な魅力を放っている。かつてのブームが去った今現在も根強い人気のあるゲームなのは確かである。
人間に知性と精神力(ときには体力)の限界を求めてくるこのゲームは古代中国の後宮に端を発すると、はたまた上海の妓院で行われていたものが始まりともいうが、この項で扱う立直麻雀は何を隠そう我が国日本の生まれである。となれば読者諸君にも囲碁、将棋と並ぶ国戯として親しんで貰いたいものである。
当然のことですが'''賭博は絶対に行わないでください。'''
この項では特に説明がない限り立直麻雀について述べます。{{Ruby|嵌|はま}}り過ぎには御注意下さい。
==牌==
この項では麻雀牌について説明する。
{| border="2" cellspacing="0" cellpadding="3" style="float:right"
|- bgcolor="#dddddd"
!萬子(マンズ)
|-
|[[Image:Mahjong-char-suit.jpeg|110px]]
|- bgcolor="#dddddd"
!索子(ソーズ)
|-
|[[Image:Mahjong-bamboo-suit.jpeg|110px]]
|- bgcolor="#dddddd"
!筒子(餅子、ピンズ)
|-
|[[Image:Mahjong-circle-suit.jpeg|110px]]
|- bgcolor="#dddddd"
!四風牌
|-
|[[Image:Mahjong-winds.jpeg|110px]]
|- bgcolor="#dddddd"
!三元牌
|-
|[[Image:Mahjong-dragons.jpeg|110px]]
|- bgcolor="#dddddd"
!花牌
|-
|[[Image:Mahjong-flowersseasons.jpeg|110px]]
|}
全部で5門34種136枚ある。5門とは万子(ワンズ)、筒子(ピンズ)、索子(ソウズ)、風牌(カゼハイ)、三元牌(サンゲンパイ)の区別のこと。
万子、筒子、索子の3門を数牌(シュウパイ・カズハイ)、風牌、三元牌の2門を字牌(ツーパイ・ジハイ)と言うが数牌はそれぞれ9種の区別があり、字牌は風牌が4種、三元牌は3種の区別がある。
これらが4枚ずつで136枚である。
数牌の内、1と9の牌を老頭牌(ロウトウハイ)と言って特別視するが、これと字牌は合わせて么九牌(ヤオチュウパイ)と呼ばれやはり特別視される。
また、数牌の2,3,4,5,6,7,8の牌は中張牌(チュンチャンパイ)と呼ばれる。
花麻雀ではこれらの他に花牌と呼ばれる物が使われる。
==その他の用具==
この項では牌以外のものについて説明する。
'''点棒'''(テンボウ)は一種のゲーム内通貨で試合終了時にどれだけ所持しているかということで勝敗が決まる。
'''賽子''' 六面ダイス二個を用いる。麻雀用の12面ダイスも存在する。
'''雀卓''' 専用の物が便利。専用マットや全自動卓なるものも存在する。
'''起家マーク''' 起家を示す。また圏風を表示する。
この他にチップ、焼き鳥マークがある。
==ゲームの目的==
麻雀では何を目的にするべきでしょう。半荘毎にはやはりトップ目を取ることでしょうか。ではより短く1ゲーム毎には、これは点棒を得ることと点棒を失わないこと。点棒を得るためにはまず和了ること。次に聴牌すること。点棒を失わない為には振り込まないこと。これらに深く関係しているのが'''ヨンメンツイチジャントウ'''という呪文である。
先ず、'''雀頭'''(ジャントウ)とは麻雀で和了る為に必要な手形の様な物で同種の牌2枚からなる。少なくとも立直麻雀ではこの雀頭なしに和了ることはできない。
次に、'''面子'''(メンツ)ですが雀頭が手形ならば面子は品物でしょうか。この品物には3つの品種がある。1つ目は刻子(コーツ)、次に槓子(カンツ)、最後に順子(シュンツ)。刻子は同種の牌3枚からなり、槓子はなんと同種の牌4枚からなります(麻雀で同種の牌は4枚しかありません)。難度の高さから槓子は刻子の4倍高い符が与えられています。順子は特別かつ最弱の面子で数牌の連なった3枚の牌からなる。数牌のみでしかも同門の牌でないと作ることができないのに符は全く得られない。明らかに作り易さの為ですが。もう一度だけ書きます。「同門の連続した並びの数牌3枚」これが順子の構成要素である。
さて、すでにお分かりのことと思いますが。四面子一雀頭とは4つの面子と1つの雀頭という意味で、麻雀の和了りの形を指す。麻雀は手牌を組み替えることでこの四面子一雀頭の完成を目指すゲームであって、また他家の四面子一雀頭の完成を阻止する(少なくとも加担しない)ゲームなのである。
例外がある。七対子と{{Lang|zh|十三么九}}(シーサンヤオチュー・国士無双)である。七対子は七種(7つでない)の雀頭を、{{Lang|zh|十三么九}}は13種の{{Lang|zh|么九牌}}(1枚が重複して雀頭を形成している事)を集める事で成立する手役で雀頭はあるが面子はない。しかし、これらの形でも和了れることになっている。
==点数計算==
立直麻雀では複雑な方法によって得失点を算出する。
先ず、和了ることで得られる得点がある。副底(フーテイ)と呼ばれるものでこれが20符ある。副底は門前清栄和の場合10符加算されますが、これは門前加符と呼ばれます。
また、摸和了った場合は自摸点2符を得られます。これは門前清でなくとも構わない。
次に部分点を見ていきます。部分点とは和了の形に付く点のことである。部分点は雀頭、面子、待ちの3つに付きます。和了形の部分に付くから部分点である。
まず、雀頭が役牌であるとき2符を得ます。連風牌の雀頭に4符を付けることもある。面子では中張牌の明刻子の2符を最低として、中張牌と么九牌、明刻子と暗刻子、明槓子と暗槓子を比べて2倍に、刻子と槓子を比べて4倍になるように符が決まっている。順に、中張牌明刻子2符、么九牌明刻子4符、中張牌暗刻子4符、么九牌暗刻子8符、中張牌明槓子8符、么九牌明槓子16符、中張牌暗槓子16符、么九牌暗槓子32符となる。さて、'''待ち'''とは何が和了り牌かという意味で使う言葉ですが、符計算では和了牌を受け入れたのはどういう部分かという位の意味である。言い換えればどういう形で和了ったかということで、単騎和(タンキホー・単騎待ち)、嵌張和(カンチャンホー・嵌張待ち)、辺張和(ペンチャンホー・辺張待ち)にそれぞれ2符付きます。
次に基本点を算出する。基本点は前述の符合算し1の位で切り上げたものに、手役とドラで得られる翻の数に2を足した数だけ2を掛け合わせたものを掛けることで得られます。
式にすると、基本点Bは符をf、翻をhとして、
B=f*2^(h+2)
となる。
ここで、基本点が2000点を超えていない事を確認して行うようにする。基本点が2000点を超える場合は役満貫となり翻によってのみ得点が決まる。
役満貫は満貫、跳満、倍満、三倍満、数え役満(四倍満)の5つがある。それぞれ基本点が満貫(5翻以上)2000点、跳満(6翻以上)3000点、倍満(8翻以上)4000点、3倍満(11翻以上)6000点、数え役満(13翻以上)8000点となる。
ではいよいよ支払である。先ず、摸和了りの場合を見ていきます。和了者が散家ならば他家の支払いは額は、散家が基本点の1倍、荘家が基本点の2倍となる。和了者が荘家の場合は、他家は基本点の2倍を支払う。栄和了りの場合は放銃者が前述の全額を負担する。つまり親満(荘家の和了った満貫)に振り込んだ場合の失点は12000点となる。
ところで、100以下の点数をやり取りできない事に気づきましたか。端数が出た場合は10の位で切り上げて支払を行う。
尚、立直麻雀の点数計算には例外がある。1、前述の役満貫に加えて2、平和形(部分点が付かない形)の摸和りは20符、3、栄和りは30符、3、七対子は25符、4、役満は四倍満となる。
この他に積符やリー棒、不聴罰符が得失点として考えられますがこれらは他の節に譲る。
==その他の得失点==
===積み符===
連荘すると積み場となる場合がある。積み場となると規定により100点棒が供託扱いとなりこれが和了者の取り分となる。例えば、1本場300点のルールで東1局1本場東家のツモ和了りとなれば各々の支払いに100点が加わる事になる。同じルールで南2局2本場南家に東家が放銃すれば支払いに600点が加わることになる。
===供託===
和了者は和了り点の他に供託された点棒を得ることができる。
====立直料====
立直者は立直料を供託する必要がある。立直料は普通1000点である。
====錯====
錯(ツオ)はゲームの進行を不可能にしないが妨げたという程度の行為で、和了り放棄とするのが普通だが規定により1000点の供託で免れられることがある。
===不聴罰符===
普通、場3000点としこれを不聴者が聴牌者に折半して支払う。例としては、2人聴牌の時、聴牌者にはそれぞれ1500点が不聴者より支払われる。
===錯和===
錯和(ツオフー・チョンボ)はゲームの進行を妨げる事を言い、発覚を以って満貫払いとする。散家の錯和の場合、散家に2000点、荘家に4000点。荘家の錯和の場合、他家に4000点ずつ支払う。
==試合を始める==
===座位と起家の決定===
座位を決めるには掴み取りと言う方法がある。風牌4種を用意し、伏せて洗牌し、各々これを取る。東を引いた者を仮東とし、その者が席を決め、その右隣に南を引いた者が、そのまた右に西が、その右に北を引いた者が座るといものである。
起家は二度振りによって決める。先ず、仮東が賽を振る。出目の数だけ仮東から右に数え、当ったものが賽を振る。賽を振ったものから出目だけ右に数え当ったものが起家となる。
===座位と起家の決定2===
上記の掴み取りと二度振りには以下の様な方法もある。
*伏せて洗牌した風牌4種を数牌の奇数と偶数の牌とで挟む。
*任意の者が賽を振り右回りに数える事で仮東を決める。
*仮東が賽を振り起家を決める。
*仮東の振った賽の目が、奇数なら奇数の側から、偶数なら偶数の側から、起家から順に風牌を取っていきます。
*東を引いた者が仮東の席に付き、右回りに南、西、北と座る。
==ゲームを始める==
===洗牌===
先ずは洗牌(シーパイ)をする。牌を卓に伏せ、静かに側面を押すことで混ぜる。
===牌山===
次に牌山を築きます。卓の淵に5枚の牌を並べてください。そして両脇に更に3枚ずつ並べる。もう一度両脇に3枚ずつ並べる。同じ事をもう一度やる。始めに作った牌の列の上に次に作った牌の列を載せます。この時、小指で両脇を押し、親指と人差し指で真ん中を持ち上げる様にする。慣れない内は半分ずつ載せる様にしましょう。
===砌牌===
次に牌山の先頭と末尾を決める。この事を砌牌(チーパイ)と言います。砌牌は一度振りによって行われる。親が賽を振り、親から右に出目だけ数えていき、当った者が自分の前の牌山でやはり右から出目だけ数え上げ、そこで右に分けます。
===配牌===
読んで字の如く牌を配ることである。東家、南家、西家、北家の順に先頭から2幢ずつ3度とる。最後に1枚ずつやはり先頭から順に取る。この時、東家はさらに第一自摸の分も一緒に取ることに成っているのですが、この行為を「チョンチョン」と呼びます。
===ドラ===
ドラ表示牌を開きます。1枚目のドラ表示牌は牌山の末尾から左、3幢目の上である。嶺上牌を落とさない様に注意して行うようにする。
==ゲームの進行==
親の打牌でゲームスタートである。ゲームは取牌(チュパイ)と打牌(ダハイ)によって進行する。取牌は後述するツモ(自摸・摸)、チー(吃)、ポン(口編に並)、カン(槓)、ロン(栄)の5つの行為のことを言い、打牌は手牌から河に牌を捨てる事とその時捨てられた牌を言います。取牌した人は和了りがないならば必ず打牌をしないといけない。
以下、取牌について記述する。
*牌山から牌を手牌に加える事をツモと言います。基本的に牌山を卓の外側から見て右端上、先頭の牌を取ることに成る。基本的にと書いたのは例外がある為である。これは後述する。
*上家の打牌を手牌に加え順子を作る行為をチーと言います。チーの手順は、先ず、チーと発声し、任意の塔子(ターツ・一枚かけた面子)を倒牌し、上家の打牌を取り、塔子の右に横にして付け、これらを自分の地の右側に置くというものになる。
*他家の打牌を手牌に加え刻子を作る行為をポンと言います。ポンの手順は、チーに準じます。発声はポンである。つまり、ポン→パタ→スッ→カッとなる。取った牌は横にして上家からとったのならば右に下家から取ったのならば左にである。対面から取った場合は間に挟む。なお、ポンはツモとチーに優先する。しかし著しく遅れた場合はその限りではありない。
*カンは槓子を作るために発声し牌を副露することをいいます。カンには3つあり、1、ツモの後、槓子を副露する暗槓。2、他家の打牌を手牌の刻子に加え合わせて副露する大明槓。3、ツモの後、副露した刻子に牌を加えて槓子を作る小明槓或いは加槓。の3つである。なお、大明槓と小明槓を合わせて明槓と呼びます。大明槓の場合は概ねポンと同じです(カンはチーに優先します)。カンをした時の特権として嶺上牌をツモることができる。嶺上牌とは牌山の末尾の牌のことである。カンをするときの発声はカンである。
*ロンは別の言い方で出和了りまたは栄和(ロンホー)または栄和了りと呼び、聴牌時のみ宣言でき、刻子、順子のみならず雀頭を作る為にも他家の打牌を取ることができます。
ところで、ツモによって和了る事をツモ和了りまたは自摸和と呼び、ツモと宣言する。前述のロンと加えて、和了(ホーラ・アガリ)と呼ばれ、宣言したプレイヤーの勝利でゲームが終了する。宣言したプレイヤーは倒牌し手牌を整理し、他家に和了りを確認させる。
さて、ツモと打牌を合わせて摸打(モーダ)と言います。打牌を取ることを鳴きと言います。この事を合わせて整理すれば麻雀は、和了りや鳴きがない限り摸打を繰り返す。というものになる。
最後に流局について述べる。流局とは和了りのないゲームの終了の事である。牌山が王牌の14枚を残して途切れた時、最後の打牌で和了りがない事を荒牌平局(ホワンパイピンチュー)或いは平局(ヘイキョク)といって、流局とする。平局したら手牌が聴牌していたものは倒牌し不聴罰符を受け取る。
流局にはこの他に途中流局と言って条件を満たせば流局させる事ができるというものがありますが、詳しくは他の節に譲る。
==試合を終える==
試合が終了した後以下の様に点棒をポイントに兌換する。このとき順位点(ウマ)やトップ賞(オカ)をやり取りし、最終的な成績とする。
0、以下の1、2、3を二着目、三着目、ラス目の者の得点に対して行う
1、得点を百の位で'''五捨六入'''し、1000で割る。
2、各々の得点から既定分の得点を引く。
3、各々の得点に既定分の得点を足す。
4、以上から得られた値を足し合わせ100から引く。これがトップ目の得点。
2では、配給原点が25000点の場合は引く数は30となりますが(二万五千点持ちの三万点返し)、30000点の場合は0となります(三万点持ちの三万点返し)。3では、トップ目から、+30、+10、-10、-30(ワンスリー)とする場合と+20、+10、-10、-20(ワンツー)とする場合の二つが多いようである。
==ルールの例==
筆者自作のルールブックを一例として掲載する。
用具
*麻雀牌
数牌
筒子 一筒、二筒、三筒、四筒、五筒、六筒、七筒、八筒、九筒
索子 一索、二索、三索、四索、五索、六索、七索、八索、九索
萬子 一萬、二萬、三萬、四萬、五萬、六萬、七萬、八萬、九萬
字牌
三元牌 白板、緑発、紅中
四喜牌 東風、南風、西風、北風
各4枚
次牌と言ったとき、前記の右に対して左。末尾は先頭に戻る。
点棒
*1万点棒4本
*5千点棒8本
*千点棒16本
*百点棒100本
*賽子
六面賽2個
*起家マーク
板状で、表に東、裏に南が書いてあるもの。
*雀卓
天板がクッション素材で覆ってあり、縁が出っ張っているもの。
重要概念
*荘家(ちゃんちゃ) 所謂親
*散家(さんちゃ) 所謂子
*起家(ちーちゃ) 最初の荘家
*仮東(かりとん) 仮の東家
*東家(とんちゃ) 荘家の事を門風から見た時東家と言う。
*南家(なんちゃ) 荘家の下家を門風から見て言う。
*西家(しゃーちゃ) 荘家の対面を門風から見て言う。
*北家(ぺーちゃ) 荘家の上家を門風から見て言う。
*上家(かみちゃ) 自分の左手側のプレイヤーのこと。
*対面(といめん) 自分の向い側のプレイヤーのこと。
*下家(しもちゃ) 自分の右手側のプレイヤーのこと。
*他家(たーちゃ) 自分以外のプレイヤーのこと。
*一度振り(いちどぶり) 賽を振り、賽を振った者始点に右回りに出目の数だけ数え上げる。
*右回り 対局人員に対して言えば始点の者から右手側にという事である。
*牌山(ぱいやま) 山にした牌。二段の井形に組み、重ねられた二枚を1幢と数える。
*河(ほー) 牌山を基準に卓の内側。
*地(ちー) 牌山を基準に卓の外側。
*洗牌(しーぱい) 牌を伏せて掻き混ぜること。
*手牌(てはい) 自分で持っている牌のこと。地に置き、13枚を原則とし、1槓ある毎に1枚を増す。
*王牌(わんぱい) 牌山の末尾の14枚のこと。
*嶺上牌(りんしゃんぱい)牌山の末尾の牌のこと。
*海底牌(はいていぱい) 王牌の直前の牌のこと。
*河底牌(ほーていぱい) 海底牌を自摸した者の打牌のこと。
*純粋な1順 鳴きの入らないという意味。
*鳴き 吃、椪、大明槓のこと。
*場 親の一巡するまでに行ったゲームを纏めて圏風から東場と呼ぶ。2巡目では南場である。
*1荘(いーちゃん) 東場、南場、西場、北場を合わせて1荘と数える。
*聴牌(てんぱい) あと1枚足せば和了ることができるという状態を聴牌と言う。また、聴牌していないことを不聴と言う。
*門前清(めんぜんちん) 鳴いていない状態の事を門前清と言う。
*老頭牌(ろうとうはい) 数牌の1と9のもの。
*么九牌(やおちゅーぱい)老頭牌と字牌のこと。
対局の基本
*対局人員は4人とする。
*東南半荘を以って一回戦とする。
*全局で和了るためには手役一飜が必用とする。
*対局の準備
*座位と起家は次の様に決める。イ、各々任意の席に着く。ロ、四喜牌4種4枚を伏せ洗牌し並べる。ハ、奇数番と偶数番の数牌でそれを挟む。二、任意の者が一度振りによって仮東を決める。ホ、仮東が一度振りで起家を決める。ヘ、ホの出目が偶数なら偶数番の奇数番なら奇数番の牌の側がロの牌の先頭となる。ト、起家から右回りに先頭の牌を取っていく。牌に従って座位を入れ替える。即ち仮東の座っていた位置に東を引いた者が座り、以下それに倣う。
*点棒は均等に分ける。
*起家マークは表を上にして起家の地の右端に置く。
ゲームの準備
*牌を洗牌する。
*牌山を組む。
*砌牌する。荘家の一度振りによって誰が砌牌するか決め、当った者は出目の数だけ自分の前の牌山で右端から左に数え上げる。当たった所が牌山の最終幢である。
*配牌する。牌山の荘家から順に牌山の先頭2幢を3度取る。次に先頭から1枚ずつやはり順に取るがこのとき荘家は第一自摸の分の牌もとる。
*ドラ表示牌を開ける。末尾から3幢目の上段を裏返す。
*賽子は荘家の地の右端に置く。
ゲームの進行
*取牌と打牌を繰り返すことで進行する。取牌した者は打牌しないといけない。
*取牌は次の4つとする。1、自摸(つも)2、吃(ちー)3、椪(ぽん)4槓(かん)
*自摸は牌山からの先頭から1枚取ること。またはカンした時嶺上牌を取ること。
*吃は上家の捨牌を発声し手牌に加え順子を作り副露する事をいう。吃は自摸に優先する。
*椪は他家の捨牌を発声し手牌に加え刻子を作り副露する事を云う。椪は吃に優先する。
*槓は他家の捨牌を発声し手牌に加え槓子を作り副露する事を云う。槓は椪に優先する。
*打牌は河に手牌から1枚牌を捨てる事を言う。また、捨てられた牌を捨牌と言う。
*槓は前述の明槓(みんかん)の他に自摸した牌を手牌に加え槓子を作り発声し副露する暗槓と、自摸した牌を発声し副露した刻子に加え槓子を作る加槓がある。
*明槓と加槓を合わせて明槓ともいい、この場合明槓を大明槓と呼び、加槓は小明槓と呼ぶことで区別する。
*槓子は副露して初めて認める。
*槓した時嶺上牌を自摸する。
*槓をすれば槓ドラが開けられる。
*海底牌を自摸した者は槓できない。
ゲームの終了
*ゲームの終了は和了(ほーら)と流局(りゅうきょく)の2つとする。
*和了は自摸和(つもほー)と栄和(ろんほー)の2つとする。
*自摸和は摸によって手役を成立させ発声し倒牌する。
*栄和は聴牌時に宣言でき、他家の捨牌を発声し手牌に加え倒牌する。
*和了した時手牌を整理し他家に確認させること。
*和了者は必ず1家として、ツモの順番の速い方を優先とする。
*流局は次のとする。
*荒牌平局(ほわんぱいぴんちょー) 河底牌で和了りがないとき。
*四風連打(すーふーれんだ) 純粋な1順目の打牌で同一の四喜牌が4枚全て捨てられる。
*四槓散了(すかんさんら) 4回槓がされる。
*九種九牌(きゅうしゅきゅうはい) 純粋な1巡目の自摸で9種以上の么九牌を揃える。
*錯和流局(ちょんぼりゅうきょく) 錯和がある。
輪荘と連荘
*荘家が和了ったとき、連荘とし、荘家は次位に移らず、積み場となる。
*散家の和了ったとき、輪荘とし、荘家は次位に移り、積み場とならない。
*荘家が聴牌しての平局は連荘とし、荘家は次位に移らず積み場となる。
*荘家が不聴での平局は輪荘とし、荘家は次位に移り積み場となる。
*四風連打、四槓散了、九種九牌では輪荘とし、荘家は次位に移り積み場とならない。
*錯和流局では連荘とし、荘家は次位に移らず、積み場とならない。
*ここでいう次位とは下家のこと。
対局の終了
*次の条件を満たしたとき、対局を終了とする。
*親番が二巡する。
*最後の荘家がトップ目のとき終了を宣言する。
*支払いのできないものが現れる。
振聴
*和了り牌を自ら捨てていることを振聴と言う。
*振聴のとき出和了りできない。出和了りとは栄和のこと。
*和了り牌の見逃しも振聴である。この場合は自己の自摸を経る事で出和了りできる様になる。
*立直後の和了り牌の見逃しも振聴である。この場合はもはや出和了りできない。
不聴罰符
*平局のとき不聴ならば罰符を聴牌者に支払う。
*不聴罰符は場3000点とし、他の不聴者と折半する。
*端数は切り上げること。
*聴牌は形式聴牌でよい。
懸賞牌
*ドラはドラは王牌の最後尾から3童目の上段が表示牌となる。
*槓がある毎に表示牌の左隣りの牌も表示牌とする。尚、暗槓では先開け、明槓では後開けとする。
*立直を掛けたものが上がったとき表示牌の下の牌も表示牌となる。
*ドラは表示牌の次牌とする。
*ドラは表示牌の枚数をH、ドラの枚数をDとして、HD(翻)を収支に加える。
収支
*和了点20符
*門前加符10符
*自摸点2符
*部分点イ、雀頭。三元牌、圏風牌、門風牌、各2符。連風牌4符。ロ、面子。中張牌明刻子2符、中張牌暗刻子2符、一九牌明刻子4符、一九牌暗刻子8符、中張牌明槓子8符、中張牌暗*槓子16符、一九牌明槓子16符、一九牌暗槓子32符 ハ、和了形。辺張和、嵌張和、単騎和各2符。
*七対子は25符とする。
*平和形の自摸和了りは20符とする。
*平和形の栄和了りは30符とする。
*基本点Eは符をf、翻をhとして E=f*2^(h+2) とする。
*イ、散家の和了りの場合、散家は基本点*1、荘家は基本点*2を支払う。ロ、荘家の和了りの場合、他家は基本点*2を支払う。
*栄和了りの場合、放銃者の責任払いとする。
*支払いは計算結果の10^1位で切り上げて行う。
*基本点が2000以上の和了りを役満貫とする。
*役満貫はイ、満貫(5翻以上)、ロ、跳満(6翻以上)、ハ、倍満(8翻以上)、ニ、三倍満(11翻以上)、ホ、四倍満(13翻以上)、の5つとする。
*基本点はそれぞれ、イ2000点、ロ3000点、ハ4000点、ニ6000点、ホ8000点とする。
*役満の基本点は8000点とする。
*不足が出たら他家が折半して負担する。端数が出たら順位が変わらない様に調整すること。
*和了形が複数通り解釈できる時は、打点の高くなる方を採用する。
積み符
*積み場の時、支払いに積まれた符の数掛ける100(点)を増す。
*積み符も放銃者の責任払いとする。
*一度和了りが出れば積み符は0に戻る。
供託
*供託された点棒は和了者が全て獲得する。
*南4局に和了りがないときは、返還される。
罰則
*次の行為を錯和とする。
*イ、自己若しくは他家の手牌を倒す。ロ、聴牌形の変わる立直後の暗槓。ハ、不聴で立直を掛ける。ニ、振聴で和了を宣言し倒牌する。ホ、自摸番ではないのに自摸する。
*錯和は競技中の発覚を以って満貫払いとする。
*錯和は他家に正当な和了のあった場合、免れる。
*錯和が在った時役満3待聴以内の手牌を持っているものはその代償を錯和者に求めることができる。
*以下の行為を錯とする。
*イ、誤って和了を宣言する。ロ、規定よりも多い或いは少ない牌を持っている。ハ、吃、口並、槓を取りやめる。ニ、吃、口並、槓をして誤った牌を副露する。ホ、誤って吃、口並、槓を宣言をする。ヘ、5枚以上の見せ牌。見せ牌とは見るべきではない牌を見せる事を云う。
*錯はその発覚を以って和了放棄とする。
*錯は訂正が可能ならば1000点を供託することで免れる。
*前述の行為の他にゲームの続行を困難にする行為を錯和、ゲームの進行を妨げる行為を錯とする。
手役
*次の手役を認める。手役の複号を認める。役満は他の役と複合しない。*は食い下がり1翻。#門前清のみ。
*立直#(イ、門前清聴牌の時、立直を宣言する事ができる。ロ、立直の発声と牌の横向けが在って有効となる。ハ、立直料は1000点とする。ニ、立直は自摸牌が在り打牌時に限り宣言し取*り消しはできない。ホ、立直の後聴牌形を変えることはできない。ヘ、和了っている牌を打って立直の宣言はできないが1巡後ならばできる。1翻)
*二立直#(純粋な一巡目で立直を掛ける。立直と複合しない。2翻)
*一発(立直を掛け、1巡以内で和了る。1翻)
*箭刻(三元牌の刻子或いは槓子を作る。1翻)
*小三元(三元牌の刻子或いは槓子が2つあり、雀頭が三元牌である。2翻)
*大三元(全ての三元牌で刻子或いは槓子を作る。役満)
*門風刻(自風牌の刻子或いは槓子を作る。1翻)
*圏風刻(場風牌の刻子或いは槓子を作る。1翻)
*小四喜(風牌の刻子或いは槓子が3つあり、雀頭が風牌である。役満)
*大四喜(全ての風牌で刻子或いは槓子を作る。役満)
*平和#(符の付かない聴牌形での和了。1翻)
*一盃口#(同一の順子を2つ作る。1翻)
*二盃口#(一盃口を2組作る。一盃口と複合しない。3翻)
*三色同順*(3色の数牌で同一の並びの順子がある。2翻)
*一気通貫*(1色の数牌で123,456,789の順子を作る。2翻)
*九蓮宝燈#(一色で1112345678999と並べ1つが重複。役満)
*三色同刻(3色の数牌で同一の数の刻子或いは槓子がある。2翻)
*七対子(対子を7つ揃える。4つ使いを認めない。2翻)
*対々和(全ての面子が刻子或いは槓子である。2翻)
*三暗刻(3つの面子が暗刻子或いは暗槓子である。2翻)
*四暗刻(全ての面子が暗刻子或いは暗槓子である。役満)
*三槓子(3つの面子が槓子である。2翻)
*四槓子(全ての面子が槓子である。役満)
*断一九*(一九牌のない。1翻)
*混全帯一九*(雀頭と全ての面子に一九牌が含まれる。2翻)
*純全帯一九*(雀頭及び全ての面子に老頭牌が含まれる。混全帯一九と複合しない。3翻)
*混老頭(一九牌のみを使う。2翻)
*清老頭(老頭牌のみを使う。役満)
*混一色*(2色の数牌を使わない。3翻)
*清一色*(一色の数牌のみを使う。混一色と複合しない。6翻)
*字一色(字牌のみを使う。役満)
*国士無双(全ての一九牌を集め内1つが雀頭に成る。役満)
*門前清自摸和#(門前清聴牌から自摸和了る。1翻)
*海底摸月(海底牌で和了る。1翻)
*河底摸珠(河底牌で和了る。1翻)
*嶺上開花(嶺上牌で和了る。1翻)
*槍槓(他家が加槓した時、その牌が和了り牌であるならば刺す事ができる。また国士無双を聴牌している場合は例外として暗槓での槍槓を認める。1翻)
*地和(散家の時、純粋な一巡目の自摸で和了る。役満)
*天和(荘家の時、配牌で和了っている。役満)
==色々な麻雀==
麻雀のルールは多様であり、様々なローカルルールが存在する。
===ありあり===
後付けルールと喰い断ルールの適用の有無を確認することがある。後付けとは役牌の刻子を作る前に他の牌を鳴く行為のこと。喰い断とは鳴いて作ったタンヤオのこと。
本来「後付けあり喰い断あり」などと言うべきところを「ありあり」などと省略することが多い。
麻雀の解説書は関東ルールを基本として書かれることが多いためか、最近では関東の「ありあり」ルールが初心者を中心に関西でも広がってきている。
*'''ありあり''' 後付けあり、喰い断あり。
*'''ありなし''' 後付けあり、喰い断なし。
*'''なしあり''' 後付けなし、喰い断あり。あまり採用されない。
*'''なしなし''' 後付けなし、喰い断なし。
=== 競技ルール ===
大会競技などの際、純粋に腕前だけを試す目的で、偶然性の強い「一発」、「裏ドラ」、「槓ドラ」などがなかったりする。
===赤あり===
赤ドラと呼ばれる牌を用いるルール。赤ドラは1枚につき1飜を得られる。数牌3門の5一枚ずつを交換するものをはじめ、五筒二枚を交換するもの、また青や金だったりすることもある。
===中麻===
台湾麻雀の事、日本の麻雀と大幅にルールが違う。
===アルシーアル麻雀===
戦前の一般的なルールで立直麻雀の原型。日本麻雀連盟では現在も公式ルールがある。
==和了るには==
役が必用である。ルールブックで有効役を確認して行うようにする。
しかし、日麻では4面子1雀頭の完成を重視して特に手役を付けることなく和了ることができます。その代表格が立直である。詳しくはルールを参照して行うようにする。
ここではまず、4面子1雀頭を完成させるために塔子(ターツ)と言う概念について説明する。
塔子とは面子から一枚欠けた牌二枚のことである。塔子には1、対子(同じ牌が二枚)。2、両面塔子(連なった数牌二枚)。3、嵌張塔子(順子の真ん中が抜けた形)4、辺張塔子(端に付いて連なった数牌二枚)。の4つがある。対子が成長すると刻子に、リャンメン、カンチャン、ペンチャンの三つが成長すると順子になる。また対子はそのままで雀頭になる。
麻雀では孤立牌を塔子に、塔子を面子にと順を追って牌を成長させていくことになる。
ところであと一枚で和了ることができるというとき麻雀ではこの状態を聴牌(テンパイ)と言います。さらに後n枚で聴牌できるという状態をn向聴(シャンテン)と言います。n向聴の自然数nを向聴数と言いますが、この向聴数を知るためのアルゴリズムがある。先ず、塔子、面子及びそれらの複合形をブロックということを覚えておいてください。
1、向聴数X。2、ブロックの個数A。3、A≦4ならば7へ飛ぶ。4、A≧5ならば対子の有無を調べる。5、対子がないA=4。6、対子があるA=5。7、面子の個数B。8、X=8-(A+B)
少しコツが必要ですが向聴数は重要な概念である。よく覚えておいてください。また向聴数は配牌4向聴が普通であり3向聴では良い方だということも合わせて覚えておくと良いでしょう。
さて、運が良ければ塔子を選択する機会が訪れます。この時頼りになるのが受け入れとロスである。受け入れとは向聴数を減らす事ができる牌の枚数のことで、ロスとはある牌を切ったときの受け入れの減る数のことである。塔子選択の時受け入れやロスが幾つか意識する事で効率よく打牌を選ぶことができる。
==麻雀の風==
麻雀には風がある。風はRPGの属性の様なもので、上手く利用することで勝を増やすことができるでしょう。
*'''圏風'''(チュワンフォン)1荘は16局であるが、これらは4局毎に東場、南場、西場、北場と呼ばれる。この東、南、西、北が圏風、所謂場風である。
*'''門風'''(メンフォン)荘家は東家(トンチャ)。荘家の下家が南家(ナンチャ)、対面が西家(シャーチャ)、上家が北家(ペーチャ)である。それぞれ、東、南、西、北が門風、所謂自風である。
*'''連風'''(レンフォン)圏風かつ門風な風。所謂「ダブ東」「ダブ南」のこと。
*'''客風'''(コーフォン)圏風でも門風でもない風。所謂オタ風。
==麻雀の龍==
懸賞牌事ドラは麻雀の龍である。一枚手牌にあれば一飜が貰える。手役ではないため一飜縛りを和了る資格はない。
ドラは表示牌の次位牌である。牌の次位は数牌ならば、同門で1の次は2、2の次は3、9は1に戻るといった具合である。四喜牌では東南西北の順で北の次は東である。三元牌は白発中、中はやはり白に戻る。
==麻雀の役==
麻雀には役がある。役者ではなく手役がである。
手役は通常40程度を使用する。直ぐに全てを覚える必要はないでしょう。一部を覚えさえすれば十分ゲームを楽しむことはできる。しかし、一度全てを覚えた後は40という数字を小さく感じるはずである。新しく役を作ってみるのも面白いでしょう。
==用語集==
*卓上 卓上に並べられた牌の山を牌山と呼びます。牌山の内側を河(ホー)外側を地(チー)と呼び、地に配られた牌を手牌(テハイ)、河に捨てられた牌を捨て牌と呼びます。
===アガリ===
*'''和了'''(ホーラ)アガリ。和了形の完成を宣言すること。
*'''聴牌'''(テンパイ) あと1枚の牌で和了れるという状態ができていること。
*'''放銃'''(ホウジュウ) 振り込み。自分の捨て牌で他家を和了らせること。
===流局===
*'''流局''' 和了りがなく局が終了すること。
以下は流局の条件の例
*荒牌平局(ホワンパイピンチュー)或いは単に平局(ヘイキョク)誰も和了せずに牌山が途切れてしまったときに流局とする。
*錯和流局(チョンボリュウキョク)だれかがチョンボを行った時に流局とする。
*九種九牌(キュウシュキュウハイ)純粋な一巡目に么九牌が9種以上ある時に宣言し流局させることができる。尚、正式名称は「九種么九牌倒牌」である。
*四風連打(スーフォンツレンタ:スーフーレンダ)純粋な一巡目に4人が同じ風牌を切った時に流局とする。
*四槓散了(スーカンサンラ)もしくは四開槓(スーカイカン)或いは四槓子(スーカンツ)。4回槓が行われたとき流局とする。
*三家和(サンチャホー)3家にロンが在ったとき、流局とする。
*四人立直(ヨニンリーチ)四家立直(スーチャリーチ)とも呼ばれる。4人が立直を行った際に起こる。
===連荘と輪荘===
*'''連荘'''(レンチャン) 条件が満たされ親番が続行する(荘家が移らない)事を連荘と言う。
*'''輪荘'''(リンチャン) 条件が満たされ親番が流れる(荘家が移る)事を輪荘と言う。
===プレイヤー===
*相対位置 左隣の者を上家(カミチャ)、右隣の者を下家(シモチャ)、向かいの者を対面(トイメン)と言う。
*'''他家''' 自分以外のプレイヤーの事を他家(ターチャ)と言う。
*'''荘家と散家''' その局の東家を荘家(チャンチャ)と呼ぶ。荘家以外のプレイヤーを散家(サンチャ)と呼ぶ。荘家、散家は親、子とも呼びます。
*'''起家''' 東1局の荘家の事。要は最初の親。
===局の呼称===
○場の□局目を○□局と言う。連荘し積み場となれば積まれた点棒の数に応じて○□局△本場と言う。流局し積み場となれば○□局流れ△本場と言う。
===一翻縛り===
和了り形には必ず手役1翻が必要とする規則のこと。ドラのみでは1翻縛りを和了る資格はない。
===度量法===
*時間
1荘=16局
1局は必ず1ゲーム以上ある。
1ゲームとは配牌(ハイパイ)から和了りあるいは平局までのこと。
*牌山
牌は2段の山に組まれる。この時、重ねられた二枚を1幢(トン)と数える。
*得点
1ポイント=1000点(100の位で五捨六入する)。
符 和了と聴牌形に付く得点。
翻(ハン) 手役とドラ、場に付いて得点を吊上げる。
===1回戦===
立直麻雀では普通1回戦は半荘行う。東風戦で行うこともある。
*'''半荘'''(ハンチャン) 多くは東場と南場を行う。
*'''東風戦'''(トンプウセン) 東場のみ行う。
{{DEFAULTSORT:まあしやん}}
[[Category:ゲーム]]
{{Game-stub}}
dv5ccuv9iw7eye0mg93bozpefifr45x
大学受験ガイド
0
3925
205819
154531
2022-07-25T06:00:22Z
133.78.37.245
wikitext
text/x-wiki
*[[受験ガイド]] > '''大学受験ガイド'''
Wikibooksで書かれている大学受験ガイドは以下の通りです。
*[[日本の大学受験ガイド]]
*[[外国の大学受験ガイド]]
*[[海外の大学受験ガイド]]
==関連==
*[[大学受験参考書]] {{進捗|00%|2013-12-06}}
*[[受験ガイド]] {{進捗|00%|2013-12-06}}
[[Category:入学試験|たいかくしゆけんかいと]]
kmzonirb6m35cttdc5yq4jhbype902i
ゲームプログラミング
0
4250
205800
205631
2022-07-24T21:54:59Z
Honooo
14373
/*セーブ、ロード、データベース*/ 節タイトルのみ変更
wikitext
text/x-wiki
<div class="pathnavbox">
* {{Pathnav|ゲーム}}
* {{Pathnav|工学|情報技術|プログラミング}}
</div>
== 概観 ==
このWiki参考書では、コンピュータを用いた[[w:ゲーム]]のプログラミングを扱います。つまり、いわゆる「テレビゲーム」や、[[w:コンピュータゲーム|コンピュータゲーム]]に関する記述についてです。
ここでは家庭用のパーソナルコンピュータで扱える範囲の事柄、それらのゲームソフトをつくるためのプログラミングについて議論します。必要に応じて家庭用ゲーム機の話題にも触れますが、あくまで派生的なものです。本書はプログラミングの教材であるので、大多数の読者が最初にプログラミングで触れるであろうパーソナルコンピュータでのプログラミングを、特にことわらないかぎりは想定しています。
用語に関して、コンピューターゲームの世界独自なものもあるでしょうから、適宜『[[ゲームプログラミング/コンピュータゲームの種類]]』などを参照してください。
== 本書の目的 ==
この教科書『ゲームプログラミング』の目的は、題名にもあるとおり、プログラミングによってゲームを作るための技術の参考資料を目的としています。
ゲームクリエイターやゲームデザイナー(絵描きではなくゲームの設計者のこと)のためではなく、プログラマーのための教科書です。
したがって本書では、ゲームとは関係の少ない一般IT企業での仕事のしかたについての記述もあれば、製造業系の組込ソフトなどに関する概要的な記述もあります。
なぜなら本書はゲームクリエイターではなく、たまたま何らかの理由でゲームを作っているプログラマーのための教科書だからです。たとえゲーム会社を退職しても、他の一般IT企業に転職してもプログラマーとして応用できることなども目指して本書は書かれています。
従って、紹介する話題が、かなりIT系、テクノロジー系の話題に片寄っています。本書で紹介するクリエイター論やデザイン論は、派生的なものにすぎません。
;本書を扱う上での注意点
特にことわりのないかぎり、本書ではC言語でのプログラミングによってゲームを作りたい読書を念頭に説明しています。
だから、ゲームの生産効率性を無視してでも、本来ならRPGツクールのような開発ツールを使ったほうが早いシンプルなゲームの場合ですら、本書ではC言語または他のプログラミング言語での開発にこだわった方法を説明している場合もあります。
;その他、本書について
このページとそのサブページだけを見ていると本書は「ゲームクリエイトの教科書かな?」と捉えられるかもしれませんが、
しかしこのページとは別に本wikibooksには「[[プログラミング]]」というページがあり、そこではC言語やJavaなど代表的なプログラム言語のwiki教科書にリンクしています。ゲーム限定の話題ではないですが、プログラミングのコードについても、そちら『[[C言語]]』や『[[Java]]』やなどの教科書のほうが(実際に動作するコードの量が)充実しています。また、Visual C++ での画面出力については『[[Windows API]]』に入門的な説明があります。
本書『ゲームプログラミング』はそういったプログラミング教科書一覧の一部でもあります。C言語やWindows API の教科書では、これをどうやってゲームのプログラミングに応用すればいいか説明できないので(本wiki『[[C言語]]』はけっしてゲーム目的のページではないので)、ゲームの実際としてプログラミングの話題を切り離すために本書『ゲームプログラミング』は存在しています。
なので本書にゲームデザイン論やクリエイター論などの内容の充実は期待できません。
本書『ゲームプログラミング』は現状、プログラマー目的以外には対応できないかもしれません。もしプログラマー目的以外の無料のwiki教科書が欲しい方は、現状では、自分で本wikiに加筆するか、あるいは本書『ゲームプログラミング』とは別に新規Wiki執筆を検討していただきたい。
== ゲームを作りたいな、よし、ゲームを作ろう。でも… ==
===しかし自分の本当の目的ってゲーム作り?===
「ゲームを作りたい」と思ったのなら、まずはあまり細かい難しいことは考えず、実際に作り始めてみるのが一番いいと思います。もちろんプログラミングについてほとんど何も知らないのなら、ある程度の勉強は必要ですが、ある程度の知識があるのなら、プログラミングの技量や知識の充実を気にするよりは、実際にゲームの完成を目指してプログラムを書いてみるのが一番いいようですよ。その過程でプログラミングの学習や経験は積んでいけますしね。JavaScriptやPython、無料でプログラミングに取り組める環境も、今現在では充実しています。
しかし、ゲームをプレイするのが好きだからと言って、ゲームを作る、までが本当に自分が好きかどうか、試しに少し作ってみたら、少し考えてみるといいですね。
例えば読者の中には、「私はRPGがすき」という人も多いでしょう。
RPG が好きという事はおそらく、よくRPGの題材になる西洋ファンタジーのストーリーや世界も好きという場合が多いでしょう。そして一方で現実のコンピューターRPGで魅力的に提供される、イラストや音楽が好きという場合もあります。
実際のゲーム業界の人々も、ゲームを彩るイラストレーションや音楽がいかに重要な要素かを語っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P85</ref>。
さて、ここで問題なのですが、「ゲームを作りたい」と貴方が思っていたとして、あなたが本当に作りたいのはゲームなのか?あるいは本当はイラストが描きたかったり、音楽を作りたいのではないか?
…というのは、ゲームというのは総合的な分野ですから、イラストや音楽はその要素として確実にありますが、それ以外、プログラミングやシナリオなど、様々な創作や創造が必要で、全ての作業量はかなり多いものになるでしょう。
そしてゲーム、コンピューターゲームにはゲーム独自の世界観があって、現実や小説や映画とは違う、独特の法則に支配された世界を作る必要があります。ある意味リアリティを持たない、リアリティから外れた世界です。だから、小説のようなリアリティにこだわるなら、ゲームは不向きかもしれません。
ゲーム作り始めの時点では、これらの判断は明確でなくても勉強目的でも構いませんが、しかその内「自分は本当にゲームを作りたいのか? Yes or no?」という疑問への答えが必要になるときがくるかもしれません。
試しにゲームを作ってみて、もし自分の本当の目的がゲームでないと分かったなら、それ以外の活動に移るのも、取る道の選択肢でしょう。
;給料は安い
職業として、商売としてゲームを作る場合、ゲームプログラマーの給料は洋の東西を問わず、安い事が知られており、書籍などでも言及されています。たとえば『CAREER SKILLS ソフトウェア開発者の完全キャリアガイド』(ジョン・ソンメズ 著)という欧米人のプログラマーの書いた本には、アメリカのゲーム業界ですらハードワークの割に賃金が低い事が記載されており、もし給料の高い仕事につきたいならウォールストリート(※米国の金融ウォール街のこと)のための仕事をするべきだと書籍中で指摘しています。
日本でも同様にゲーム業界の報酬が低いことは知られており、多くのゲーム会社の伝記漫画でも、よく語られています。
アニメーション業界と比べたら、ゲーム業界のほうが報酬が高いことは事実かもしれませんが、これは実は恐ろしいことに、アニメーション業界の報酬が異常に低いだけで、アニメーション業界よりはましだけど、結局は…というのが現状でしょう。
=== 同人ゲーム以外の発表の場 ===
2001年ごろの日本はネットを活用した同人ゲーム黎明期、フリーゲーム黎明期で、実験的な時代でもあり、多くのイラスト愛好、創作者や音楽創作者がゲーム制作に手を染めていたようです。この頃、まだイラスト投稿サイトや小説投稿サイトといったものは無かったか、あったとしても小規模でマイナーなものでした。
しかし2010年のあたりから各種の投稿サイトが普及したことにより状況は変わり、むしろ現在では、小説やイラストを発表したい人はそのジャンルの投稿サイトに直接アクセスしたほうが早く、そのためゲームを通して発表するのは人によっては廻り道かもしれません。
それをわかったうえで、それでもゲーム制作に身を投じるかを考えた上で、「よし、自分はゲーム制作をしよう」と思えるなら、ゲーム制作をするのが良いでしょう。
実際、今現在の作曲家やイラストレーターは、ゲームに関わったとしても、専門家として楽曲やイラストを提供するという立場に過ぎない場合もあり、自分自身が主体になってゲーム制作をする人は、プロアマ問わず少数派のように見えます。
同人ゲームの世界でも現在は(2021年頃に記述)、プログラマー系の作者が圧倒的に多い様です。
しかし、専門外の人だからこそ、メディアミックス的な意外な視点で新しいものが作れる可能性もあるかもしれません。コピーライター、作家の糸井重里が、マザー2の企画にたずさわった例もあります。しかし、あくまで「可能性」であり、成功はけっして保証されてはいないので、読者の自己責任でお願いします。
今現在のゲーム専門学校のカリキュラムはプログラミングが主体です。CGの授業は、週に2時間程の様。一方でゲームCG、或いは、一般CGに特化した学科もある様です。
あるWikibooks編集者Aは、もしイラストを描きたいなら、イラストの世界で描くのが安全、と考えています。ゲームプログラミングについては、プログラムを書ける人は絵コンテも描けそうだし、基本的にある程度の作図的なイラストを描ける人は多いだろうから、別にプログラミングに専念しろとは思っていません。
さて、読者がゲーム制作を職業として目指すのかどうかはともかく、とりあえず、ゲーム業界の状況を知っておくのが有用でしょう。
結局商業界の状況が権威をもってその分野を支配しているのがこの社会の基本なので、趣味でも職業でも、業界周辺のことを知っておくのは得ることが多いはずです。
文献『レベルデザイン徹底指南書』では、現実世界で自分が新しいスキルを1つ覚えたら、古いスキル1つはどれか忘れる必要があることを説いています<ref>大久保磨『レベルデザイン徹底指南書』、2016年12月14日 初版 第1刷発行、P81</ref>。著者は、最初はグラフィッカーでしたが、しかしプランナーに転職したので、グラフィック関係の技能は仕事では「忘れて」しまった、という内容を述べています。ただし、比喩的に「忘れる」とは言っていますが、実際には忘却し無くなってしまったわけではなく、仕事では時間の都合により両立できないので、グラフィック関係の技能は例え話で「忘れた」、のであり、現実にはグラフィッカー時代に培った観察眼をプランナー時代の現在でも活用している、と、書籍中では述べられています。
このことは職業、あるいは技能とは一般的にそういうもの、と考えることができるでしょう。
{{コラム|漫画家大塚志郎のアドバイス|
同人ゲーム界では、ゲーム制作と、イラストまたは作曲などを一人で兼ねている作者も、ある程度は居ます。一方ネットの世界には様々な簡単に利用できるフリー素材もあるので、イラスト作画や作曲をしなくてもゲーム制作は可能ですよね。
一人でイラスト作画や作曲をしながらゲーム制作をするのはある意味マルチタレントだとも言えますが、現実にその創作をしている人たちは、かなり年長のこの分野の熟練者が多いようです。若い19歳ぐらいの頃に、それらマルチジャンルを両立するのは、一般にかなり困難なことだと思われます。
漫画家の大塚志郎は、漫画家を漫画創作の手本にするならデビュー時代を手本にするのが良い、と、漫画家向けの技法の教育漫画で語っています。
大塚は、漫画家の人生のうちで、これからデビューを目指している新人に近い境遇にあるのは、ヒット後の漫画家の生活状況ではなく、まだ無名・マイナーな時代の態度・生活だ、と描いています。成功後の熟練した漫画家より、若いデビュー直後の作家をお手本にするのがいいだろう、という主張ですよね。
さて、それでもデビュー時代から複数ジャンルの同人活動を均等に兼業する意思が硬いなら、それはそれでひとつの考え方ですが、上述のリスクを知っておく必要があるでしょう。
}}
===ゲーム業界は産業のエンジン役?===
かつてはゲーム産業が、日本のIT産業やデジタル家電産業の中心的・牽引(けんいん)役であった時代がありました。しかし、2010年以降、この考えは当てはまらなくなっています。
PlayStation2あたりまでの時代は、経済評論誌の未来予想でも、「もしかしたら今後、家庭用の据え置きゲーム機がパソコンの代替品として、家庭のリビング家電の標準品になるかもしれない」という予想があった。ゲーム産業がそのような牽引役として、経済界から期待されていました。ソニーが国産CPUをプレステ2〜3に搭載したり、WindwosのマイクロソフトがXBOXでゲーム機に参入したり、そういう時代です。
しかし2020年代の今は違います。結局、2020年代のゲーム機に使われてる技術や部品は、パソコン用の部品や技術の流用、ゲーム機のCPUも、今やインテルなどのパソコン用CPUをゲーム機でも使っています。
もはや現代は、ゲーム業界は、産業のエンジンではないようです。
ですから今現在、新しい技術に興味ある人は、ゲームにこだわらず、直接的にその技術を勉強し改良したほうが近道です。
たとえば、インターネット技術を使って何か新しい事をしたいなら、ゲームを作るよりもwebアプリやサーバーwebサービスを作るべきだし、目的のネットワーク用ソフトウェアをそのまま制作したほうが早いし確実です。
古い経済知識の先入観にとらわれず、無理にゲーム制作にこだわらないほうが、自分自身の技能やキャリアも開けていくでしょう。
2010年に出版された商学書籍『メイド・イン・ジャパンは終わるのか』には、「しかしながら、ファミリーコンピュータで世界に攻勢をかけ、その後圧倒的な強さを誇っていた日本の家庭用ゲーム産業も、90年代末からはその競争力にかげりがみえはじめた。日本の国内市場は伸び悩み、成長率は鈍化傾向にある(図表7-3)。」とあります<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.263</ref>。
その「図表7-3」の統計値によると、
:ファミコン発売の1993年には2268億円、
:スーファミ発売の1990年には2430億円、
:プレステ1発売の1994年には3882億円、
:1995年には急成長して4769億円、
:1997年には4795億円で、ほぼこの頃がピークであり、
:2000年には3768億円にまで低下(プレステ2の発売年)、
:2005年には3151億円まで低下(XBOXの発売年)、
である。(青島らが『レジャー白書』、『情報メディア白書』、『月刊トイジャーナル』、『CESAゲーム白書』などをもとに作成した図表の統計値です。)
<!-- ところで前編集者Sさん,これって正確には何の数字,金額なの?それを後で書き足しておいてほしいんだけど…。あれかな?一年のこの国のゲーム産業の売上高? -->
また、2010年の時点の商学研究では、1997年を境に、ゲームソフト市場で競争する企業数が増加傾向から減少傾向に転じた<ref name="m289">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.289</ref>、とも言われています。
書籍『メイド・イン・ジャパンは終わるのか』にも、引用文「家庭用ゲームは日本がその本格的立ち上げを主導し」<ref name="m91">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.91 </ref>と書かれているぐらいで、1990年代は日本のインパクトが強かったようです。
なお、携帯電話の分野で、日本は国際的な地位を喪失したのに対し、デジタルカメラとゲームは「現代」(参考文献の著作時2010年ごろ)でも日本が主要な地位にある<ref name="m91" />。
{{コラム|ゲームが産業の牽引役だと語った人物|
1998年頃、アニメ評論家の岡田斗司夫が、未来予想の一貫として、「これからゲーム機が、(パソコンではなく)家電の中枢になるだろう」というような内容の未来予想をしていました。たしか、岡田の著書『東大オタキングゼミ』(自由国民社、1998年)で、このような未来予想が読めます。岡田の東大での講義を加筆修正してまとめた書籍なので、実際の講義はその数年前に行われていたのだろうと思います。
岡田の東大での講義は東大生のその後の進路、官僚や大企業のビジネスマン達に大きな影響を与えただろうし、若手新進評論家として、この国の政治・経済人達も、その言論を参考にしただろう。
実際、2008年(リーマンショックあたり)くらいまでの日本の家電業界の投資は、ソニーがゲーム機のCPUを作ったりと、岡田の予想を参考にしているような面もありました。
ですが実際の2001年以降の家電業界の結果は予想とは少し外れました。まず
:* そもそも、冷蔵庫もエアコンも全然デジタル化(IoT化)されず、家電のほとんどが外部からのコンピュータ制御を必要としない状況。
:* 個々人が持ち歩いているデジタル家電は、携帯ゲーム機ではなくスマホになった。
:* パソコンは多くの家庭にいまだにインターネット用端末などとして残り続けている。
一方岡田は東大オタキングゼミで、98年当時の時点で任天堂が莫大な現金資産(たしか数千億円ほど)を持っていることに注目しています。
一般の大企業は、現金ではなく株券や不動産などの形で資産を蓄えています。しかし任天堂は、銀行口座の現金だけで数千億円という、非常に資金力の高い企業でした。今や日本を代表する世界的なゲーム大企業になっています。
また、日本だけでなくマイクロソフトのXBOXなど、実際に欧米の企業も昔はコンピュータゲームが産業の牽引役だと思って、先をこぞってゲーム機に参入していたわけでもある。岡田の未来予想は、決して根拠の無いものではなかったのです。
}}
{{コラム|読書について|
ゲーム業界と関連のない文献も、この教科書では出典として書かれていますが、これはこの頁の主要執筆者Sが、多量の市販本を読む以外に知的活動の方法を知らないことと、自分自身の文章の権威と信頼性を、著名人の威を借りて確立したいからでしょう。
ゲーム業界を志望するなら、ゲーム業界人の書いた本は少なくとも何冊かは読んでおくといいでしょう。
ネット上では、業界人ではないのにもっともらしく書かれた文章も多いですし、おそらく本Wikiの執筆者にも本格的なゲーム業界関係者は一人もいないでしょう。
業界人達のSNS発言ではなく、現代では書籍があるので、実際に書籍を手に入れて読むのがいいですね。書店で販売される書籍というのは、けっして著者だけの意見でなく、編集者や校正者、周辺の職業人達が査読をして、内容の信憑性を確認しています。
<!-- ニュース解説者の池上彰(いけがみ あきら)が、たしか2011年くらいのテレビ番組で言っていたことだと、編集者Sは言っている。 -->
何十冊も本を読むよりはプログラミングを書く実践のほうが重要でしょう。
『ゲームデザイン プロフェッショナル』著者であるFGOクリエイターも、ゲーム開発の書籍は読んでおくべきだと忠告しています<ref>『ゲームデザイン プロフェッショナル』、P234</ref>。また、ゲームデザイン本で学んだ知識は、ゲーム業界以外でも仕事術として活用できます。たとえば上司への業務報告の報告・連絡・相談(ホウ・レン・ソウ)などの考え方は、ゲーム業界でなくても活用できます<ref>『ゲームデザイン プロフェッショナル』、P332</ref>。
いっぽう、もし最新IT技術を勉強したいなら、読むべきは、ゲーム制作の解説本ではなく、そのIT技術の解説本など、そのものの書籍を読むほうが近道でしょう。
}}
===ゲームプログラミングは面白い。しかし、そんな楽な事ではない。===
ここでいう「プログラミング」とは、C言語などのプログラム言語による開発のことです。RPGツクールなど開発ツールによるゲーム制作の話は原則していません(本書『ゲームプログラミング』はあくまでプログラミングのための教科書です)。
さて、よくネットや、あるいは日常でも(C言語などによる)「ゲームプログラミングは簡単だよ。イラストやシナリオのほうが難しい。」、などという人がいますが、この発言の心は、「俺はプログラミングもイラストもシナリオも出来る凄い男だぜ。しかもプログラミングなんて簡単だし、むしろクリエイティブなイラストやシナリオの方に精力を費やす偉い奴だぜ^^」という、世間に良くいる武勇伝、自慢を語りたがる、インチキ親父が吹かしているだけなので、あまり真面目に取り合わないのが正解だと思います。
まず第一に、不当にプログラミングの価値を貶めている言説ですよね。
Visual C++またはVC# 、あるいは Direct Xなどを使ってプログラミングすることは、そんなに簡単なことではないでしょう。
ゲームプログラミングの入門書などには、初心者でも理解できそうな比較的簡単ないくつかのサンプルコードがありますが、それは初心者でも簡単に書けそうな技術だけを抜粋してるという、あくまで例外です。
RPGならたとえば、ドラクエ3のような戦争画面の行動順を処理するソート機能をつくるだけでも一苦労ですし、ほかにも道具・アイテムなどの自動整理をはじめとする標準機能を作るだけでも一苦労です。
決して上手い人のサンプルコードをコピーアンドペーストをして終わりという訳にはいかず(そもそも現状そのようなサンプルコードがネット上に無いですが)、もし仮にサンプルコードがネットに公開されていても、自作品に組み込む際にさらにそれをデバッグ(決してテストプレイの意味ではなく、実際にコード修正が必要になります)しなければならず、プログラミング言語の理解が必要です。
ゲームのプログラミングは決して楽ではないし、仮にもし楽だとしたら、じゃあゲーム会社のプログラマー職の人の仕事は何なんだ・・・という疑問につながりますよね(デマを言ってる人は、この疑問を脳内に都合よく無視しますが)。
ツクールやエディタのような制作ツールを使えば、C言語的なプログラミングは不要ですが、それはそのツクールなどのツールを開発している人達にプログラミングを肩代わりしてもらっているだけなので、決して「ゲームプログラミングが楽」、ではないでしょう。楽だというなら、じゃあツクール開発元の角川書店およびその発注先ソフトメーカーのプログラミングが楽だとでも言うのか・・・(デマを言ってる人はこの疑問を無視します)。
そもそもコンピューターゲームというのはプログラミングがなければ成立しないのですから、そのプログラミングの価値を貶めて平気な人は、コンピューターゲームにかかわる資格はないでしょう。
== ゲーム制作に関する留意点 ==
=== IT的な留意点 ===
====プログラミングなしでも同人ゲームを作れる====
自分でゲームを作る際、必ずしも、C言語などプログラム言語で記述する必要はありません。
プログラミングをせずに、ほぼマウス操作と会話メッセージなどの文章のキーボード入力だけでゲーム開発をできるようにするソフトウェアが、有料または無料で発表されています。
たとえば、RPGを作りたいなら、日本で発表されているソフトでは、『[[w:RPGツクール]]』や『[[w:WOLF RPGエディター]]』などのように、RPG製作に特化された開発ソフトがあり、大幅に開発の手間を減らせます。なお、『RPGツクール』は有料製品です。『WOLF RPGエディター』は無料ソフトです。
アクションゲームを作りたいなら、『[[w:アクションゲームツクール]]』があります。これらツクール製品は有料製品です。(なお、かつて『[[w: 2D格闘ツクール2nd.]]』というのがありましたが、しかし現在ではサポート切れのため、今現在の市販の十字キーコントローラーが初期設定では動かない、一部のボタンしか使えないなど問題点があります。)
また、ノベルゲームを作りたいなら、フリーソフトの『[[w:吉里吉里Z]]』などがあります。吉里吉里Zはソースコードが公開されており、オープンソースになっています。
:なお、とりあえず「ゲーム開発ツール」と呼びましたが、じつは呼び方は特に決まってはいません。「ゲーム制作ツール」と呼ぶ場合もあります。ゲーム開発ツールのことを「ゲームエンジン」と言う場合もありますが、開発ツール以外のゲーム用ランタイムのことも「ゲームエンジン」という場合があります。
:本Wikibooksでは、とりあえず、ツクールや吉里吉里シリーズやウディタ(WOLF RPGエディター)などのソフトの呼び方は、まとめて「ゲーム開発ツール」または「ゲーム開発ソフト」と呼ぶことにします。
C言語などによるプログラムは、上記のゲーム開発ツールを使わない場合の選択肢になるでしょう。
既存のゲーム開発ツールの仕様に不満を感じる場合に、「じゃあ自分でプログラムして作ろう」となり、プログラミングが必要になるわけです。
なお、上記の開発ツールはほとんどがWindows用のソフトです。MacやLinuxでは動きません。MacやLinuxで動作するゲームを作りたい場合は、別のソフトウエアを使う必要があります。
既存のゲーム開発ソフトを使わずにプログラムを組んでゲームを自作する場合、必ずしも既存のツールのような、ゲーム作品と開発ツールが分離された仕組みを再現する必要はありません。
一般的に初心者が、ゲーム開発ツールを作ることはほぼ不可能です。初心者は開発ツールを作ることは考えずに、まず1本、とりあえずゲーム自体を完成させてみましょう。開発ツールを自作したいのなら、まず先にゲーム1本を完成させたあとに、あとから開発ツールとゲーム作品の分離などに取り掛かるのが推奨です。
==== 商業ゲームの開発言語 ====
基本的に、現代の商業ゲームは、C言語で開発をする。
ただし、ファミコンの古いゲームは、アセンブラで開発されていた。ファミリーコンピューターからスーパーファミコンに至るまで、OSは搭載されていない<ref name="m289" />。
ではいつからC言語がゲーム開発に使われるようになったかというと、商学の学説では、プレイステーション(※ おそらくプレステ1?)の頃からだろう、と考えられている<ref name="m289" />。ただしこの時代でも、処理速度の高速化のためにアセンブラにアクセスする開発チームも少なくなかった<ref name="m289" />。
また、プレイステーションのOSは独自仕様である<ref name="m289" />。
カプコンなど一部の企業は、OSによる開発ではなく、移植性を高めるために自社製の内製フレームワークを用いて開発する。カプコンの場合、2010年頃は「MTフレームワーク」という自社製フレームワークを用いて開発を行っていた<ref name="m289" />。
{{コラム|ゲーム用のメーカー独自プログラミング言語について|
ゲーム開発ソフトには、ゲーム開発用の独自のプログラミング言語を持っている場合があります。このような機能の実現方法は、原理的には、ファイル入出力の関数を使い、テキストファイルの文字列を読み取って、文ごとにプログラム動作を設定・実行している、と、考えられます。インタプリタは、このような方法で作られています。
ゲーム製作ソフトでの独自のプログラミング言語はたいてい、コンパイル作業を必要としないので、おそらくインタプリタ方式でしょう。
基本的にWindowsの場合、実行ファイルに変換するには、Visual Studio というマイクロソフト社の配布している開発環境が必要です。
Visual Studio が開発環境を提供していない独自言語は、たいてい、インタプリタ方式となると思われます。
コンパイラ方式に比べて、インタプリタは処理速度が不利なので、適用できるジャンルや用途が限られます。たとえば3Dアクションゲームには、インタプリタ方式は不向きでしょう。
これらの独自言語を使うにしても、自分自身で独自言語を作りたいと思うとしても、この教本ではまず、既存のプログラミング言語を使ってゲーム制作を開始することを推奨します。
}}
====ゲームのプログラム言語の歴史====
ゲームを書くために利用される言語は多岐にわたっています。歴史的にはゲーム業界でも、[[C言語]]や、特に計算機のスピードが重要になる場面では[[w:アセンブリ言語|アセンブラ]]を利用してプログラミングを行うことが普通に行われていました。<!-- (文献)→-->そのため、ゲームプログラミングは通常のプログラミングと違った技能が必要であるように思われていました。
現在では計算機がある程度速くなったことや、ゲームプログラムの開発を複数人で行うことでテクニカルなプログラミングが避けられるようになったことにより、ゲームプログラミングは他の一般のプログラミングと同じような課題だと見なされています。
しかし、特にアクションゲームなどのリアルタイムでの画面書き換えが必要なゲームで、プログラムのスピードが重視されることは変わっていません。また、コンピュータの性能があがるにつれ、それらの性能を全て引き出すように表現手段が変化してきたため([[w:3次元コンピュータグラフィックス|3D]]、[[w:ポリゴン|ポリゴン]]などを参照)、状況によっては複雑で特殊なプログラミングが必要になることもあります。
===== 初心者が使えるプログラミング言語 =====
ゲーム開発において、一般にゲームショップなどで流通している商業ゲーム作品において、現在よく利用されているプログラミング言語として、[[C言語]]、[[CPlusPlus|C++]]、[[Java]]があげられます。
Windowsの3DエンジンのDirectXは、主にC++を想定しています。なので負荷の高いアクションゲームを作りたい場合、Visual C++での開発が安全でしょう。
しかし、ネット上のフリーゲームでは、C++以外の言語が使われることも、よくあります。
さいきんゲームエンジンとして有名なUnityは、言語としてはC#の文法を採用しています。
[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
市販の書籍では、Pythonによるゲーム開発を紹介した出版物もあります。ただし Python は原理的にインタプリタ方式であるために処理速度がC++に劣り、アクションゲームなど負荷の高いゲームを作る事を目指している場合は、将来的にはPythonからC++への装備変更が必要になるかもしれません。
===== ゲームに適さない(だろう)言語 =====
;Flash関係
例えば、かつて Adobe の Flash が、ブラウザで動かせるゲームを作る際に、よく使われていました。このようなwebブラウザ上で動くゲームのことを一般に、「ブラウザゲーム」と言います。ただし、現在ではFlashは廃止の方向です、すでにほぼ廃止されているといっていいでしょう。また、現状では、ローカルPC環境でのゲームをJavaScriptで作るのは、アマチュア段階では困難です。JavaScriptのアマチュアゲームと言う事例を聞きません。
;JavaScript
なお、JavaScript はクロスプラットフォームですが、しかし、セキュリティ上の理由などから、いくつかの機能(たとえばファイル入出力)がwebブラウザ上では使えないようになっており、そのため、JavaScript だけでゲームを作るのは、初歩的なゲームを除くと、かなり困難です。(おそらく、オンラインゲームでは、サーバー側でPHPやサーバサイドJavaScriptなどの別プログラムが走っていると思われます。)
セーブ機能の必要なゲームを作る場合は、JavaScriptでの開発は選択肢にない(セーブの実装には、JavaScript国際規格にはない非標準仕様を使いこなす必要があり、かなりの技術力を要するでしょう)。
=====ブラウザゲームの初歩的な原理=====
商品として流通するようなゲームや、高度な機能を持つブラウザゲームを作ることはとても難しく、このページでは手に負えません。そこで、このページでは、初心者が練習用につくるゲームを例に記述します。
webブラウザだけで動くのがブラウザゲームです。ブラウザゲームを作るのに使う言語の第一選択肢はJavaScriptです。サーバー側の処理が必要ならPHP,Python,Perl,Javaなどの言語の出番でしょう。
「ネットワークゲーム」は「ブラウザゲーム」とは意味が違います。
「ブラウザゲーム」は、パソコンにwebブラウザさえあれば、ネットワークに接続していなくてもゲームプレイできて、最後、クリアまでプレイできる作品もあります。
しかしネットゲームは、ネットワークに接続しないと、ゲームを開始することさえ不可能です。つまり、サーバの提供するゲームが「ネットワークゲーム」「ネトゲ」です。
もしPHPやPerlなどでゲームを作る場合、普通はネットゲームになる筈なので、作者がサーバを構築して提供する必要がありますし、プレイヤーにはゲーム中にサーバに接続する環境が必要になります。提供者は、サーバを用意したり、保守管理する必要がありますよね。サーバーがダウンしてしまうと、プレイヤーがゲームをできなくなります。
「PHP ゲーム」などの単語でネット検索したり、あるいは書店でプログラム言語の書籍や解説サイトを見ると、ときどきPHP・Perlなどの言語でゲーム開発しているものもありますが、一般的なダウンロード型のゲームとは違う筈なので、気をつけてください。
{{コラム|ソケット通信、ほか|
コンピュータプログラムからインターネットに通信するには、いくつかの方法がある。
C言語の場合はOSの提供するソケット通信といわれる機能を使う方法、
JavaScriptにあるHTTP通信の機能を使う方法、
などがあるだろう。
ただし、JavaScriptでゲームを制作するのは、セキュリティ上の制約などからセーブロードが標準的方法では困難など、とても制作が難しい。
よって本セクションでは、C言語にソケット通信を組み込むことの概要を説明する。
ゲーム制作初心者がソケット通信までする必要はないが、将来的には知る必要があるかもしれない。
本wikiではWindowsの場合については 教科書『[[WinSock]]』、
macやLinux / Unix や BSD の場合は 教科書『[[Unixソケットプログラミング]]』 で説明している。
Windowsとそれ以外のOSとで、ソケット通信の仕様が微妙に異なる。
ソケット通信では文字コードの問題がある。手元のパソコンの文字コード設定は、通信相手方の端末には反映されない。
Windowsの日本語版では、伝統的に Shift-JIS といわれる文字コードが使われてきたが、海外のWindows端末は日本の文字コードにあわせてくれないし、macやLinuxやBSDも同様に日本には合わせてくれない。
簡単な対処法として、ゲーム中では日本語を送受信しない、つまり半角の英数字と記号だけを送受信する、という道はある。
会員登録などのためにどうしても氏名や住所などの日本語を使う必要がある場合、PHP・Pythonなどサーバ言語に対応した「フレームワーク」があり、そのフレームワークが最初から日本語に対応、もしくは設定を少しいじるだけで日本語対応するので、それを利用すれば効率的かもしれない。
ゲームとは別途、サーバー側にフレームワークをインストールして、会員登録時にサーバー側でそれを使うようにすればいいだろう。
しかしゲーム内では日本語の扱いは非常に難しい、限定されるという事になるだろう。
C言語のプログラムにサーバサイドの言語・システムを組み込むのは難しいから、ネットゲームではどこかでソケット通信に頼ることになるだろう。
市販の本を探しても、そもそもソケット通信の書籍自体がめったに見当たらないし(ほんの少しだけ出版されている)、もし見つけても全く文字コードの問題の解決方法は紹介されていない(2021年現在)。
}}
====プラットフォ-ム====
;ライセンス料
一般に、プレイステーションや任天堂のゲームを開発するには、専用の機材が必要であり、そのため、ソニーや任天堂とライセンス契約しなければいけない<ref>『ゲームプランとデザインの教科書』、P.107 </ref>。
その契約に際して、ライセンス費用または料金と呼ばれるものを、ゲーム機開発会社の任天堂、ソニーに支払う必要があります。
現在でもソニーや任天堂のゲーム機用のソフト開発・販売には、ライセンス料が必要です。少なくともPS4やニンテンドースイッチのパッケージソフト開発には、「ライセンス費」が必要<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.120</ref>。
なお、書籍『ゲームプランナーの新しい教科書』によると任天堂やソニーのようにゲーム機を作っている会社のことをハードメーカーと言います。つまり、ゲーム機のハードメーカーにライセンス料を支払うという仕組みになっています<ref>『ゲームプランナーの新しい教科書』、P20</ref>。
また、スマートフォン向けアプリは、プラットフォーム使用料が掛かります。
書籍『ゲームプランとデザインの教科書』によると AppleStore, GooglePlayともに売上げの30%とのこと<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.121</ref>。その他のプラットフォームも、大体同じとのことです(参考文献の著作の時点では)。
Google やAppleのようにプラットフォームを提供している企業のことをプラットフォーマーと言います<ref name="gp244">吉冨賢介『ゲームプランナー入門』、P244</ref>。
昔からゲーム機のライセンス料は有料で高額であり、ソニーや任天堂の収益源のひとつになっている<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.267 </ref>。一方、パソコンゲームにはライセンス料が無いのが普通です<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.283 </ref>。
なお、ハードメーカーでなければプラットフォーマーでもないゲーム会社のうち、製造から販売までを手がける会社のことをパブリッシャーといい、たとえばカプコンやコナミやセガやスクウェア・エニックスやバンダイナムコなどがパブリッシャーです<ref name="gp244" />。
実は、必ずしもパブリッシャーが開発を手がけるとは限らず、スマホ向けアプリなどではディベロッパーといわれる開発専門の会社に委託している場合もあります<ref>吉冨賢介『ゲームプランナー入門』、P245</ref>。
;ポリコレ規制
Apple社のAppStore向けのスマートフォンアプリでは、アップロード後に、公開前にAppleによる審査があり<ref name="g139">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.139</ref>。、審査は欧米基準です。
GooglePlayは、公開前の審査はないが公開開始後に海外基準で審査されるので、それに違反していると配信停止になります<ref name="g139" />。
海外プラットフォームで販売・配布したい場合、「ポリティカル・コレクトネス」(政治的な正しさ)といわれる、海外の公序良俗の基準に配慮する必要があります<ref>『ゲーム作りの発想法と企画書のつくりかた』、P.235</ref>。
欧米の判断基準が、アジア諸国やアフリカの生活習俗に合致しない場合も多いのですが、欧米のIT大企業はその欧米基準での規制が政治的に正しいと考えているでしょう。「日本では、少し考え方が違う」と言っても、通用せず規制される場合も多い。
ゲームだけでなくテレビアニメでも、漫画ワンピースの海外アニメ版では、主人公側の若者がタバコを吸っているシーンをアメ玉に作画を変えられたり、ドラゴンボールに出てくるミスターポポという肌の真っ黒なキャラクターの肌を青く書き換えたり、色々な例があります。
ポリコレとは関係ない事例ですが、TVアニメーションのポケットモンスターで主人公のサトシ達がお握りを食べているシーンで、アメリカ版ではドーナツになっていたことがあります。これは、国による食文化の違いを示していますよね。
===プロトタイプ===
ゲームでは、曲や絵が良くても、ゲームとしては今ひとつ面白くない、という事は起こり得ますよね。
ですからむしろ、商業的なゲーム制作では、イラストは簡略なものを使ったうえで、プログラム中心の試作品(プロトタイプ)をいくつか作り、その中でゲームとしての面白さがあるものを、取捨選択したうえで商品化を考え、その後イラストや楽曲を詰めて完成度を高めていく、と、いう制作過程を取るようです。
書籍『ゲームプランナー入門』(吉冨賢介 著)によると、商業ゲーム界では、企画書に書かれたゲームが本当に面白いかどうか確認するために、「プロトタイプ」が作られます。プロトタイプの段階では、プログラマーと、企画の意図を考慮するためプランナーも関わります。<ref name="gp17">吉冨賢介『ゲームプランナー入門』、P17</ref>
イラストレーターは、プロトタイプの前段階あたりでイメージイラストを提供し、スタッフ間の共有イメージを作ります<ref name="gp18">吉冨賢介『ゲームプランナー入門』、P18</ref>。そしてプロトタイプ進行中は、グラフィック案の提案をしていきます<ref name="gcw56">蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P56</ref>。サウンドも同様、プロトタイプでは、曲調を固めていく段階です<ref name="gcw56" />。
:※時々あるトラブルとして、マイナーな同人ゲームや零細メーカーのゲームで、背景イラストや脇役キャラクターなど目立たない部分で他社のイラストが使われていることがあるようです。おそらく試作用に流用したイラストが、そのまま製品に混入したのでしょう。こういうトラブルがあるので、他社イラストの使用は試作であっても避けるべきです。
;実装検証
プログラマーは、そのゲームでコアになるプログラムやシステムやミドルウェアについて、プロトタイプ段階で実装検証を済ませておく必要があります。プロトタイプより前の原案の段階では、利用するミドルウェアの洗い出しをして、出来る範囲での基礎実験をしておきます<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P54</ref>。
ミドルウェアによっては使用料が発生するので、その点を事前に調べておく<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P55</ref>。
プロトタイプのうち、張りぼての例えば画面だけの物等を、「モックアップ」といいます。一方である程度遊べる状態まで作っているものを、「プレアブル」といいます<ref>STUDIO SHIN『ゲームプランナーの新しい教科書』、翔泳社、2018年3月10日初版第2刷、P251の図</ref>。
ゲームデザイン本ではよく「プロトタイプ」という表現が用いられるので、本ページではこの言葉を使うことにします。
{{コラム|商標権等|
知的財産権には著作権・商標権・意匠権などがありますが、商標権は特に強い権利であり、気を配る必要があります。
意匠権とは、建物や工業製品の外観に関する権利なので、ゲーム制作ではあまり気にする必要はないようです<ref name="gpd135">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.135</ref>。
「特許権・実用新案権」と「商標権」は、事業者によって国に登録されている権利で、かなり強力な権利なので、気をつける必要があります。
特許権や実用新案権とは、大まかに言えば、技術的な発明に関する権利です。商標が登録されているかどうかは、特許庁の『特許情報プラットフォーム』というwebサイト<ref name="gpd134">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.134</ref>で確認できます。
商標をトリッキーな意図で登録する人も多く、自社でビジネス展開をする気がなかったり、他社の商品などでまだ登録されていない物を申請したり、そういうやや不正な登録申請でも認可されてしまう場合も多いです。
また、商標は業種のジャンルごとに分かれているので、たとえば携帯電話のジャンルが新たに追加された時代に、過去のゲームの商標を登録した人がいました。そのため携帯ゲームを出せなかったり、商標を買い戻したり、取り戻すための裁判をするのに時間とお金がかかってしまったり、様々な問題が発生します。<ref name="gpd134" />
著作権は、登録の必要がなく、著作をした時点で発生する権利です。
『ゲームプランとデザインの教科書』によると、こういう事柄にまだ慣れていない人によくあることなのですが、他人の個人サイトやSNSで公開されていた絵や曲などを、許可なく勝手に使う事例があるようです<ref name="gpd135" />。
二次利用を許可されてない著作物は素材として使えません。
そして見落としがちなのが、フォントの著作権です<ref name="gpd135" />。フォントにも著作権があります。
フリー素材と書かれていても、商用販売が禁止されている配布形態のものもありますので、気をつけましょう。
}}
{{コラム|アイデアの権利。アイデアとは盗まれるのか、盗むのか?|
商業ゲーム作家たちの、2022/1時点でのSNS発言によると、業界全体でみられることですが、会社外部の人がアイデアを一方的に投稿してきて、会社で作った作品にそのアイデアと類似点があったら、アイデア使用料を要求してくる、そのような問題に悩まされているようです。
そこでゲーム会社側では原則、
:送られてきたハガキやメールは、まずクリエイター以外の事務系の人間が読む。
:もしハガキなどにアイデアがあった場合、そのハガキを処分。
などの方策を取ると言われています。
また、偶然や何らかの理由でアイデアが一致してしまった場合に備えてのリスク回避として、事前に会社のウェブサイトなどで「弊社にアイデアが送られてきた場合、そのアイデアは弊社のものになります」のような宣言をしている会社も多くあると言われています。<!-- (以上、作家のSNS発言やそれを紹介したサイトの取材などのまとめ.)←出典を消すなってS氏はやたら云うんだけど,そんな重要な事かね?もちろん全くなくて,いい加減な事書いていいと言ってるわけではないけど… -->
ここで前編集者は娯楽産業の世界には厄介な消費者がいると言及しているけど、この前編集者自身がこのWikibooks で異常なまでに厄介な参加者なんだが、そろそろ人のふり見て自分を返り見るべきだと思うな。
法学的には、著作権法はアイデアを保護しません(『アイデア・表現の二分論』と言います)。
そして前編集者はアイデアに関して権利をどうこう言う人間を無知だと書いているけど、自分は至上の賢人だと思ってるようだね。
そしてこの人物は他者を愚弄する時は必ず自分の意見ではなく、権威ある人がそう書いたから、出典だからと宣う。
出典は岡田斗司夫氏の著作『東大オタク学講座』や『マジメな話』だそうだ。
まあ岡田氏ならかなり過激なことを書くのは事実だろうが,この前編集者S はその悪徳をさらに10倍に高めてこのWikibooks に記述する地獄のように厄介で無知で馬鹿な人間だ。
}}
任天堂『ゼルダの伝説 ブレス オブ ザ ワイルド』は、プロトタイプの段階ではイラストや音楽を組み込まずに(イラストは、代わりに大きなドットの塊などで代用する)作られている事がゲーム業界見本市イベント CEDEC 2017 で公開されています<ref>https://game.watch.impress.co.jp/docs/news/1078888.html 2020年11月25日に閲覧して確認</ref>。
プロトタイプの段階では、画像や音楽は発注せず、骨組み的なプログラムだけで、そのゲームのアイデアが「はたして本当に面白いか?」を、実際に社内の関係者にプレイさせてみて確認します。
因みにプロトタイプに関しては『[[高等学校情報/その他の技術的な話題#プロトタイプ開発]]』の記述も参考になる。
ここでいう「プロトタイプ」(試作品)とは、コンピュータプログラムのゲームとして動作するのが前提です。映画製作でいう絵コンテ試写のように、ゲームの試作では、なるべく早期に第三者が試作ゲームを遊べるように作っていく必要があります。
プロトタイプという言葉を使用すること自体が妥当かどうか。まず、書籍『ゲームプランとデザインの教科書』で使われている<ref name="gpd350">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.350</ref>。
ニコニコ動画の経営者、川上量生が使っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日 第1刷発行、P.38</ref>。川上は角川書店も買収したので、おそらくそこ(カドカワ・RPGツクール販売元)でも使っているでしょう。
ゲームのプロトタイプの基本姿勢は、「汚く作って、やりなおす」です<ref name="gpd350" />。もちろん最低限のプログラムの知識、勉強は必要ですが、あまり知識収集や理解充実を気にするより、実際に作ってみることを優先したほうがいいようです。チーム制作をしている場合はプロタイプは赤ん坊であり、そのチームで育てていこう、我々の子供だという意識で接しているようです<ref name="gpd350" />。
勉強に関しては、汚くてもいいからまず工夫して作ってみると、何を勉強すればいいかが見えてきます。
英語では「quick and dirty prototype」という言葉があります<ref>川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.349</ref>。
書籍『ゲーム作りの発想法と企画書のつくりかた』によると、シナリオライター志望者が企画書やシナリオ案をメーカーに送りつけても、あまり効果的ではないようです。
それよりゲーム形式でシナリオを書いてしまうのがいいようで、「CHR:ヒロインA(私服)、表示」のような文章を織り交ぜて構成していくのが推奨<ref>『ゲーム作りの発想法と企画書のつくりかた、P.140</ref>。
参考文献のその章では、シナリオライター志望者に向けて語られていますが、プログラマーを目指すならどうすればいいでしょうかね。
プログラマー志望なら、サンプルゲーム、サンプルプログラムを作ってしまうのがいいかもしれません。
1990年代、週刊少年マガジンに不定期掲載していた読みきり漫画『ゲームクリエイター列伝』では、カプコン社のゲーム『バイオハザード』を扱った『バイオハザードを創った男達』の際、制作過程でゲームデザイナーが大幅な作り直しを判断して進行させた、という描写があります。(ただしWikiboooks一編集者の記憶、詳細はあいまい)。
のちの、ゲーム評論家の阿部広樹の評によると、むしろそれは劇的な大きな決断ではなく、ゲームデザイナーの日常の普通の仕事ではないか、と語られています。
どんな肩書の人間だろうと、すでに決まって進行していた方針をひっくり返すのは、かなりのストレスのある判断で指摘になりますが、一般に漫画や映画、あるいはNHKの仕事に関するドキュメンタリーでもそうですが、職業や職業者の物語では、過剰に対象を美化し、劇的な演出によって関係者を称賛し、英雄視する傾向があるように思います。
{{コラム|アイデアはアイデアで価値がある。でも、せっかくなら、それを試作して、形にしてみよう。|
ゲーム業界人広井王子は書籍のインタビューで、自分の社長としての人材評価は「0点」から始まる「加点法」だと語っていたようです。
『ゲームデザイン プロフェッショナル』著者も、文脈は違いますが「加点方式で物事を考える」と述べています<ref>『ゲームデザイン プロフェッショナル』、P224</ref>。
正直インチキなゲーム業界人の点数勘定などには全く興味ないが、そんな話とは全く別に、ゲーム制作の上で、実際に動く簡単なプロトタイプを作ってみることは間違いなく有意義な事でしょう。
アイデアはアイデアとして、思考や思想の展開としてありますが、それを具体的な形にしてみることは非常に楽しくエキサイティングで、意味ある活動ですよね。
}}
仕様書や設定資料を超えて、誰もが遊べる試作品は、意味のある企画行為でしょう。前編集者は、時間軸・動きの制作意図の明確化、という言葉を使っています。もちろん短くまとめること自体もなかなか難しいのですが、工夫を凝らして、ゲームプログラムを完成させることが重要な経験であり、思考の具体化でもあると思います。
===アルファ版===
アルファ版はプロトタイプとは違うもので、その後段階で、ゲームの全体像が分かる一部分を、商品に準じた形で作ることです<ref name="gp17" />。
アルファ版でもそのゲームが本当に面白いかどうか検証がなされます。サウンドやビジュアルは商品に近いほぼ完成化された形で取り込みます。
アルファ版の使用の結果、プロジェクト中止の決定がなされる場合もあります<ref name="gp18" />。
ベータ版とは、会社によって意味が多少違いますが(たとえば『ゲームデザインプロフェッショナル』と『ゲームプランナ-入門』とでも微妙に違う)、おおむね、とりあえずのゲーム、最初からエンディングまでのほぼ完成状態をひととおり遊べる制作物です<ref>『ゲームデザインプロフェッショナル』、P170</ref>。
細かいバグ修正はこれらの段階では後回しにします。
基本的に
:プロトタイプ→アルファ版→ベータ版→調整→デバッグ
の流れですね。
===プロトタイプ制作に必要な予備知識===
====数学は後回し====
ゲーム制作の作り始めにおいて、必要な数学や物理の予備知識は、それほど多くありません。
文献『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』によれば、数学や物理の習熟に拘って、それに多くの時間と精力を費やして勉強するよりは、3Dの勉強などで必要を感じたら、そのつど、その分野の数学や物理を学ぶのが効率的だと述べており、また可能なら実際にプログラミングでその理論を試してみると具体的に理解をしやすいと述べています<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P88</ref>。
====C言語の予備知識は入門書1冊+αで十分====
C言語を使ったゲームは、予備知識はそれほど多くないので、あまり難しいことは考えず、まず実際にプログラムを書いて作ってしまう事優先にするのが正解なようです。
市販のC言語入門書で、配列や関数などの一般的な機能を一通り習得したら、あとはVisual C++ で映像出力とキーボ-ド入力のみを、1~2週間ほど勉強、そしてVisual Studioを起動してゲームを作り始める。
うまくいけば数か月以内に、パソコン用の非ネット通信のゲームを作ることができるでしょう。
ただ、ゲームプログラミングを試みる人は、必ずしもゲーム制作のみが絶対的な唯一の目標ではない可能性もあるので、それぞれの立場に応じて、座学を取り入れてみるのもいいと思います。
== 作業リストを作る ==
===作業リストの制作開始の方法===
さて、ゲームを作る時は、アイデアを頭の中だけに置いておくのではなく、文章に書きだしてみましょう。
そして、壮大な長大なアイデアではなく、1週間~1ヶ月ていどで成果の確認できそうなアイデアだけを書いてみましょう。
次にそのアイデアを、実際に動作するプログラム、ソフトウェア(つまりプロトタイプ)にするために、具体的などんな機能を持ったプログラム(簡単なものでよい)を制作しなければいけないか、自分のやるべきことのリストを、箇条書きで作ります。<ref>https://www.youtube.com/watch?v=J5FCZG7dfEY 2020年3月17日に閲覧</ref>
IT界ではこういうリストを「ToDoリスト」(読み: トゥードゥーリスト)とか「タスクリスト」といいます。このページではむしろ日本語で、「作業リスト」と呼んでみましょう。
さて、このリストを作るときは、作業項目は具体的かつ単純な目標に分割します。ですから例えば RPG の戦闘システムを作るときは、
*「戦闘システムを作る。」
と、あいまいに総体的に書くのではなく、具体的に、
*戦闘画面のメッセージ表示欄および標準メッセージを作る。
*「戦う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは後回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
という風に、作業項目を細かく分割していきます。
こうすることで、作業がひとつずつ比較的に簡単な要素に分解されていくので、楽になります。また、バージョン管理ソフトを使って管理している場合も、上記のような作業リストの分解をしておけば、各バージョンの概要を書く際にも作業リストの項目が転用できるので、一石二鳥です。
予定日は書かないほうがいいように思われます。スケジュールを管理したい場合は、別にファイルを作るといいですね。
そして書き出した項目を優先順位で並べたら、最初の作業リストは完成です。
===作業リストの更新===
プログラミングする前に作業リストを眺めて、そして上の項目から実際に作業を開始しましょう。
そして一つの項目を完成させましょう。
そして作業項目がひとつ終わったら、「【完了!】」等、そういう情報を、項目の前または後ろにつけます。備忘のための記録ですね。
たとえば、
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
こうします。
以前の記述を残したまま、その作業が終了したことを示しておくわけですね。
また、もし追加の作業が必要になったら、たとえばダメージ計算システムを作るために、ランダム計算が必要になって、自分がそのプログラム言語でのランダム計算に詳しくないなら、たとえば
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
::※3行目に追加されています。
と、必要に応じて項目を追加します。
さて、これから行う作業を検索しやすくするため、たとえば
'''やることリスト'''
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
'''完了した作業'''
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
の様に完了した項目を後回しにしたり、或いは
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*(現在→) Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
のように、(現在→)、を追加するのも良いでしょう。
つまり作業の記述をそのままに、どこまで進展しているかが分かる等に書き足していくわけですね。
==プロトタイプ制作における創作面の検討事項==
===ゲーム性===
「ゲーム性」という概念があって、これがあるからこそゲームは面白く、魅力的だと考えられています。
プレイステーション開発元のソニーもこれを重視していますし、一般的に多くのゲーム愛好者、関係者たちもその考えに同意するでしょう。
ではゲーム性とは何か?
ゲームのジャンルにもよりますが、「駆け引き」や「戦術」、これが「ゲーム性」だとよく言われます。
『ゲームプランとデザインの教科書』によると、ゲーム性とは、シューティングやアクションでは「対戦の駆け引き」、RPGでは「戦闘と物語の介入」、シミュレーションゲームなら「戦略性」だそうです<ref>『ゲームプランとデザインの教科書』、P152</ref>。
ただし上述の書籍によると、1990年代は今よりもゲーム性とシステムが重視されていたとの説明があるので、裏を返せば2010年以降の現代では、ゲーム業界ではゲーム性の重視の比率は1990年代よりも減っているかもしれません<ref>『ゲームプランとデザインの教科書』、P302</ref>。
『ゲームプランナー入門』(吉冨賢介 著)では、ゲーム性とは「課題や挑戦の仕組み」であると結論づけています<ref>吉冨賢介『ゲームプランナー入門』、P36</ref>。そして、この達成感こそが「ゲームならではの面白さ」だと述べています。
;アクションパズルゲーム「I.Q」
メディアクリエイターの佐藤 雅彦氏(「だんご3兄弟」や「ピタゴラスイッチ」等を手掛けている)が、初めてかかわるコンピュータゲームで、ソニー・コンピュータ・エンターテインメントとの共同企画で、のちに「I.Q」(1997年にシリーズ第一弾を発売)と呼ばれるシリーズに携わった時、プロトタイプが全くゲーム性のないものになってしまい、それをプレイしたソニーの幹部陣の顔色が非常に曇ってしまったようです<ref name="br67">川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P.67</ref>。
ここでの悪い反応、薄い反応の理由がわからなかった佐藤氏が、階段の踊り場でソニーの新人に尋ねてみると、「それが、あの、ゲーム性がないっていうか・・・」と言われたと出典の対談集に書かれています<ref name="br67" />。
基本的に佐藤氏は、プロトタイプの企画を提案しただけですが、ソニーにはプロトタイプを作るための部署があるらしく、1~2ヶ月かけてそこでプロトタイプが作られたようです。
この問題の責任が誰にあるかは、大した重要な事ではありませんが、商業作品としてプロトタイプを作る以上は、どこかの段階でゲーム性を意識して、プログラムに盛り込む工夫が必要になるでしょう。
===ゲームの見た目とは?===
ふつうゲームのプレイヤーは、まず最初にそのゲームの「見た目」を判断し感受するでしょう。ですからその見た目のインパクト、興味を呼び起こす構成が必要になります。
例えばスーパーファミコンRPG『新桃太郎伝説』では、開発当初はドラゴンクエスト5 のようなマップ画面のトップビューUIでしたが、開発中にクォータービューの他社製RPGが発売されて高い評価を得たので、マップUIを(トップビューではなく)クォータービューに作り直したようです。このことは攻略本『新桃太郎伝説 究極本』に開発裏話として書かれています。
一方現在でもこの方向の試みは重要なようで、書籍『ゲームデザイン プロフェッショナル』の著者は、他企業の製品の画面と、自社の製品を目で見比べる分析方法で、自分たちの製品のUI の問題を見出しています<ref name="gdp199">『ゲームデザイン プロフェッショナル』、P199</ref>。
割と素朴で単純で即物的な見た目、「かっこいい」とか、「ぱっと見派手」等の要素が非常に重要なようです<ref name="gdp199" />。
商業としてゲームを作る以上は、ペイしなければ企業も事業の継続も維持できませんから、考慮せざるを得ない問題ではあります。
== ゲーム開発ツールを使う場合 ==
====開発ツールのライセンス条件====
ゲーム開発ツールのなかには、そのツールで開発したゲームソフトに義務として「この開発ツールで開発したソフトウェアは、ソースコードを必ず公開しなければならない」などの条件をつけている場合があり、このような条件を「開示義務」(かいじ ぎむ)または「ソース開示義務」などといいます。
ソース開示が嫌な場合は、開示義務のあるツールは使わないのが正解ですね。
ゲームに限らず、ソース開示を義務としている開発ツールは多くあるので、ライセンスには気を配る必要があります。
「有料ソフトの販売を禁止」とか「アダルト作品の開発は禁止」などの条件をつけている場合も、ありえます。
ですからゲーム開発において、ツールのライセンス条件の確認は、非常に重要です。
{{コラム|GPLライセンス違反|
GPL(ジーピーエル)というライセンスがあって、Linuxなどのオープンソースで使われています。このGPLを組み込んだプログラムは、ソースを公開しなければいけません。
ですから、ソース公開したくないプログラムには、GPLソフトウェアは組み込めません。
ゲーム業界でも、GPLライセンスのソフトウェアを組み込んでしまったために、呼出し元ソフトウェアでのソースコードの一部を公開することになったゲームがあります。2005年頃、『ToHeart2』という美少女ゲームが、xvidというGPLソフトを取り込んだ疑惑によって、GPL違反の疑いでソース公開になりました。([[w:ToHeart2#GPL違反とソース公開]])
GPLでも、たとえばLinuxサーバ上でソース非公開のアプリを動かすように、GPLのソフトウェアを非公開ソフトとは独立した状態で使う場合は、ソース公開の必要はない、と、考えられています。(これが必要有りとなると、オンラインのプログラムやネットゲームは全てソース公開しなければならなくなり、非合理な結果になる。)
特定のプログラム自体に、GPLソフトウェアのコードを取り込んだ時、ソースコード公開が必要になります。
}}
{{コラム|BSDライセンス他|
オープンソースの中には、どのような利用法であっても、利用者にソース公開を求めないライセンスもあります。BSDライセンスとMITライセンスはソース非公開で利用できます。
ゲーム制作ツールの吉里吉里Zは、修正BSDライセンスで公開されています。
もしライセンスのことがよくわからない、またはライセンスの学習に時間をかけたくないなら、オープンソースのツールを使うなら、BSDライセンスを使うのが安全です。
}}
[[w:DXライブラリ]]は、GPLでもBSDライセンスでもありません(DXライブラリ説明書「DxLib.txt」には、どこにも「GPL」とも「BSD」とも書いていない)。DXライブラリは単にソースコードが公開されていて、著作権者の「山田 巧」氏が著作権を保持しているオープンソースなライブラリです。
このように、ネット上でソース公開されているソフトウェアには、ライセンスの複雑な解釈を嫌ってか、「BSD」や「MIT」などのライセンス条件を名乗らないオープンソースソフトウェアもあります。
{{コラム|自作ソフトでソース開示|
昨今ではオープンソースやフリーソフトウエアの発展などの背景もあり、「自作ゲームのソースコードやソースファイルも開示しよう」と思うゲーム作者もいるかもしれません。
然しソースコードを開示していることが原因で、トラブルに巻き込まれる場合もあるかもしれません。自分の作ったゲームのコードが悪用され、トリッキーないたずらや嫌がらせ、誹謗中傷などを受ける可能性も全くないわけではありません。
そこでライセンスに、利用による損害に対する保証が無いことを明示するのは、ある程度有効でしょう。大抵の著名なフリーソフトウェアライセンスには、この条項があります。他者の悪意を完全に防ぎ失くすることは難しいのですが、ある程度の対策は見出されていますし、自身でも見出していく必要があるでしょう。
}}
====開発ツールを使用しないという事====
下記の理由(機能制限および移植性の悪さ)の問題から、あまり大規模な作品は開発ツールでは作らないでおくのが安全です。
大規模な作品の場合、Visual C++ などでコードを書いて開発することを推奨します。
=====機能制限=====
ゲーム開発ツールを使う場合、そのツールにもよりますが、「○○ができない」、つまり特定の目的を果たすための機能を持っていない場合があります。
Visual Basic や Visual C++ には普通にある関数でも、開発ツールには無い場合も多い。
また、もし、いったんはゲーム開発ツールを使って目的の機能を持ったシステムを作ったとして、さらなる機能をそのシステムに追加しようとするときに、大幅な作り直しが必要になる場合があります(拡張性の悪さ)。
システムがモジュール化されていても、そのモジュール部分では大きく改変する必要がある場合もあるでしょう。
ですからゲーム開発ツールによるゲーム制作では、あまり大作を作ろうとしないほうが安全です。開発ツールで作る作品は、比較的に小規模な作品に、とどめておくことを推奨します。
Windowsの場合、本来なら Visual C++ などを使って、プログラム文法のいろいろな事に留意しながらプログラムを書きますよね。開発ツールを使う場合、 Visual C++ のコードを書かずに、ほぼマウス操作だけでプログラムを作ろうとしているわけですから、何かしらの制限があります。拡張性の悪さは、プログラム文法などの学習の負担を減らすためのトレード・オフのようなものですね。
=====移植性の悪さ=====
また、もうひとつの問題点として、C言語への移植性の悪さがあります。
ソースコードが公開されていない開発ツールの場合、異なる開発環境にゲームのソースファイルを移植するのは、ほぼ不可能です(仮に、開発ツールのランタイムを模倣できたとしても、著作権などの法的な懸念が生じる可能性あり)。
ゲーム開発ツールで作ったソースを、Visual C++のソースに置き換えるのは、簡単にはできないし、ほぼ全面的に新たに書くことになるでしょう。
==イラストレーター、デザイナー==
ゲーム制作、業界において、イラストや音楽を作る部署、人物は、まとめて、"アーティスト"と呼んでいるようです。
ゲーム界の場合デザイナーというのは、プランナーやディレクターのことであり、管理職的な設計者のことで、美術的なクリエイターではない。design という英語には、機械建築の設計という意味もあります。
映像関係、画像系のアーティストはグラフィッカーと呼ばれることもあります。ムービー担当者、特にゲーム界では3D-CGの制作者をアニメーターと呼ぶことが多いようです。アニメーション業界では主に、手描きの原画、動画マンをアニメーターと呼びますが、最近は3D-CGアニメーション映画も多いので、すこし状況が変わっているかもしれません。
ゲーム業界とアニメーション業界、各会社企業、過去と現在で、「原画」「仕上げ」「絵コンテ」等、一般的な作業に関する言葉が、それぞれの状況で微妙に違った意味で使われることも多いですね。
…ところで前編集者はわざわざこの項目を作ったうえで、色々な場所での言葉の意味の違いを、クドクドと自分勝手な分かりづらい説明で長々述べた後、「混同しないように気をつけましょう。」なんて馬鹿馬鹿しい言葉で締めているんだけど、この人物の意図はどこにあるのだろう?
例えばデザイナーというのは一般的に、造形作品、図案、意匠を考案する人のことを言うのだから、ゲーム界の外の人間が多少その業界内での意味を取り違えても、それほど致命的なミスでもないし、罵倒、愚弄されるいわれもなければ、好き放題にその相手を罵倒、愚弄していいわけでもない。間違えて使っている人を見たら、その都度やんわりと教えてあげればいいだけじゃあない? だいたいその世界に現実に身を置いたら、そこでの言葉の意味、使い方なんて自然に覚えるものだし…。
それを得意げにこれが違うあれが間違いといちいち理屈書いて、いい気になって威張っているこの人物は何者なのだろう?
現編集者が思うには、この人物は、学問、知識、知恵、科学とは何かという事を、根源的に取り違えている、のだろう。
==操作性==
操作性について、親指と人差し指<!-- ←ここ,中指って書いてあったけど,こっちだよね? -->だけでボタンプッシュなどの操作ができるように作成するのが基本です。中指、小指、薬指はコントローラのホールドに使うぐらいです。人間工学的に、小指や薬指は力が弱いので、微妙な操作には向かないことが知られています<ref>川上大典ほか『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.48</ref>。
一般的にゲームプログラミングでは、
# プレイヤーからの入力を扱うことができる。
# ゲームが提示する内容を表示することができる。
入力と出力、この2点が機能として必要になります。
プログラミング言語とプレイヤーからの入力については歴史的にも、あまり変化がありません。言語では主に[[C言語]]、[[C++]]が用いられる。[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
パソコンゲームでは、プレイヤーからの入力には通常、キーボードかマウスを利用します。他に[[w:ジョイスティック|ジョイスティック]]や[[w:ゲームパッド|ゲームパッド]]が利用される場合もあります。家庭用ゲーム機では[[w:コントローラ|コントローラ]]が利用されることが多いのですが、[[w:ニンテンドーDS|ニンテンドーDS]]や[[w:Wii U|Wii U]]では[[w:タッチパネル|タッチパネル]]、[[w:Wii|Wii]]では複数の入力機器が提供されることが発表されています。各種入力機器をプログラムから扱う手法自体は、普遍性があり、入力機器ごとに大きく変化しない、と、考えられています。[[w:デバイスドライバ|デバイスドライバ]]、[[高等学校情報B]]には、プログラムから周辺機器を扱う方法について多少の記述があります。
画面表示のうち、3Dの表現は割合難しく、ある程度の数学(高校、あるいは場合によってはそれ以上)の理解が必要でしょう。2Dに関してはプログラムの面では、さほど難しい部分はありません。
==処理速度の問題==
基本的にプログラミングでは、関数を使って、処理をコンパクトにまとめ、定数ではなく変数で柔軟性のある操作をすることが求められますが、ゲームの場合は、この構造のせいで処理速度が低下することがあります。
現在のCPUの性能、速さはかなり高くなってはいますが、プログラム処理は無限に煩雑化できますから、やはり高度な処理を短時間でなすことが求められます。特にゲームは、リアルタイムの反応のタイミングが非常に重要ですからね。数学の指数計算についての雑学で、「新聞紙を42回おりたたむと、月に届く距離になる」というものがあります。(新聞紙の厚さ)*2^42、ですね。もっとも新聞紙の物性から言って、ほぼ不可能な操作ですけど^^;;。コードの内容、組み合わせによっては、このように計算量が指数関数的に膨大になってしまい、処理速度が非常に遅くなってしまう場合があります。
ですが、このセクションで後述するように、関数を用いる場合の解決策(※概要:あとでdefineやinlineに置き換え)があるので、プログラミングの初期のほうは、とりあえずバグを未然防止するために関数を活用するべきでしょう。
1980年代頃のファミコンなど古い時代のゲームでは、ストレージ容量(ハードディスク容量のこと)が、ボトルネックでした。「容量不足でイベントをいくつか削りました」と、当時のRPGなどのゲーム作家が述べるのは、ストレージ容量の不足のことですね。ただ当時のファミコンはROMカセットでハードディスクは無いので、まさにストレージ容量という言葉が適切でしょう。
しかし2010年以降の現代では、ボトルネックになっている要因は、ストレージ容量不足よりも処理速度です。
ゲームプログラミングに要求されるコード特性は、科学計算ソフトウェアや金融プログラミングなどの手法とは異なります。情報工学・情報科学で適切とされる「構造化プログラミング」などの歴史的に発展してきたプログラミング・パラダイムの理念とは反するようなコード開発方針になる場合もあります。しかしゲームプログラミングに限らず、限定されたハードウェアで特定の結果を速く得るためには、様々なトリッキーな手管が必要になるでしょう。
;ツクール等制作ツール
RPGツクールの制作元のカドカワ(アスキー社→エンターブレイン社→カドカワ(かつての「角川書店」) )では、PRGツクールでのアクションゲーム開発は推奨していません。アクションゲームの場合は、同じカドカワの「アクションゲームツクール」で制作するよう、薦めています。
アクションゲームとターン制RPG では要求される特性が大きく異なり、なかには、ほぼ対立しているような性質もあります。
ツクールやウディタでも、万能にあらゆることがスタマイズできるわけではなく、その制作ツールの特性に依存しますし、主に処理速度の低下しない部分についてユーザが創作できるようになっているでしょう。
多くのRPG制作ツールはマップ操作や戦闘画面の基本システムのルーチンそのものは、あまりカスタマイズできません。画像や音楽は挿入できますが、例えば戦闘プログラムなら、「コマンド」の命令文など一部の派生的な部分だけが独自に作れる程度でしょう。
ですから、ツクールでどうしてもアクションRPGを作りたい場合、基本システムの改造はかなり困難だろうし、別途、アクションRPGのような動作をするマップイベントを作成する・・・ぐらいでしょうね。
ツクールやウディタでターン制RPG以外のジャンルを制作するのには、実質的には限界があり、さまざまな制約が生じます。
;具体的な手法
初期段階では関数や変数を活用してプログラミングし、処理速度を高める必要がある箇所にだけdefineマクロ等を用い別の方法に置き換える。C++ならinline関数という前処理命令もあります。
通常の関数で記述していったソースコードを、あとから一括変換などでdefineマクロやinline関数などに置き換えることは比較的に容易です。
また、関数を経由しているので、マクロを使った場合でも比較的にバグが混入しづらくなっているかもしれません。(defineなどの前処理命令マクロは、用いるとバグを発見しづらいので、なるべくマクロの利用を避けるべきなのが、ゲームプログラミングに限らないプログラミングの定石です。)
一方、まったく関数を使ってないコードを、あとからdefineマクロなどに手作業で置き換えるのは、なかなか面倒です。
最終的には一括変換で置き換えることが出来ますから、途中の段階では、処理速度を気にせず関数を使うのがいいでしょう。
なお、defineマクロは、値の置換以外には用いないのが、プログラミングの定石です。このため、たとえば黒色RGB値の<code>10,10,10</code>といった配列にdefineマクロを使うべきかどうか悩みますが、とりあえずなるべく値周辺にだけdefineマクロを適用するようにするようにするのが良いでしょう。いっぽう、一般の命令文をdefineマクロで置き換えるのは、避けるべきでしょう。
たとえば、処理に0.5秒ほどの時間の掛かってもかまわないような場所は、どんどん、関数に置き換えていっても良いかもしれません。
アクション性のないゲームなら、関数をぞんぶんに活用できます。
ターン制RPGやシミュレーションゲーム、アドベンチャーゲームなど、関数を活用しやすいでしょう。
一方、アクションゲームなどでキャラクター操作中のコードのように頻繁に使って、しかもそのゲームの中心的なコードなら、そこは最終的には関数にしないほうが良いかもしれません。
このように、ゲームのジャンルによって処理速度に対する必要な水準が異なりますので、プログラミング時における関数などの利用の方針も異なります。
以上のように、何でも関数にすることは避けるべきです。関数は処理速度の問題がありますので、必要性のある部分だけ関数にするべき。関数を使わなくても、for文やif文などのブロックの構成を適切に組み合わせることで、コード中のmain関数以降の部分でコード共通化できることは色々とあります。
「共通性のあるコードだから」といって、大して長いわけでもないコードを関数に置き換える事は、速度維持には寄与せず、ゲーム制作のプログラミングとしては、悪手となるでしょう。
===2Dの画面出力===
画面出力の場合も入力機器の場合と同じで、これらを操作する方法はOSごとに異なっています。先ほどあげた GTK+, Qt, SDLなどのライブラリはクロスプラットフォームの画面出力を提供しているため、これらを利用することで全てのプラットフォームで動くプログラムを作ることができます。<!--画面出力を扱うためには近年の[[w:ビデオカード|ビデオカード]]の発展についても見る必要があります。しかし、ビデオカードの機能は2次元の描画に関してはあまりあらわには見えないので、この話題は3次元の描画を行うときに再び戻ってきます。-->
*[[ゲームプログラミング/ブロック崩し]]
*[[ゲームプログラミング/画面出力]]
==目次==
=== ジャンル別のプログラミング手法 ===
==== 3Dグラフィック ====
* [[ゲームプログラミング/3Dグラフィック]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
==== RPG ====
* [[ゲームプログラミング/RPG]]
==== アクション ====
※未作成
==== パズル ====
※未作成
==== シミュレーション ====
※未作成
=== ゲームのデバッグ ===
* [[ゲームプログラミング/デバッグ]]
=== 入力 ===
OSの種類によって、キーボード入力やマウス入力の受け付けのさいのプログラムの書き方は違う。
Windows API での具体的な手順は『[[ゲームプログラミング/入力]]』で説明する。
=== ゲームエンジン ※未完成 ===
* [[ゲームプログラミング/Unity]] ※リンク先ページの編集者が現状ではUnityの著作・調査を放棄中なので、調べ物としては役立ちません(2021年12月19日に本文を記述)。
=== 非プログラミングのゲーム製作の関連作業 ===
==== バランス調整 ====
*[[ゲームプログラミング/バランス調整]]
厳密にはプログラミングの話題ではないが、ゲーム製作では必要な知識なので、サブページで説明する。
:※ゲームデザインに関する記述をここに集積し分離したい、という編集者の意図もある。
==== ゲーム用の書類の書き方 ====
説明書や仕様書(しようしょ)の書き方については、『[[ゲームプログラミング/書類]]』で解説する。
== 未分類 ==
===Visual C++プログラムによる文字画像の出力===
Visual Studio付属のフォームデザイナ(VSの用意するGUI自動作成ソフト)によるGUIオブジェクト作成では、RPG用には使いづらい。いや、ひょっとしたら上手に使う方法はあるのかもしれないが、様々な理由で難易度は高い。
そこでまず、Visual C++で、フォームデザイナをなるべく使わずに文字や映像を出力する方法を考える。
選択肢は、幾つかある。
1.フォームデザイナを1つも使わない方式
*Windows APIで入力していく方法。(Wikibooksに『[[Windows API]]』の入門書があります。)
*DirectXで入力していく方法。DirectX自体はWindowsAPIを利用している。
2.1つだけフォームデザイナのパネルを使う方式
*フォームデザイナで「パネル」という画像表示機能のコンポーネントを一つ用意して、そのパネルで表示する画像をゲーム内のストーリーなどに応じて切り替えるだけで、すべての画像表示を行う。
フリーソフトでゲーム用ライブラリの『HSP』はWindows API を呼び出す仕組みになっています(HSP関連のサイトを見ると、Win APIプログラミングの解説をしている場合もある)。
フリーソフトでゲーム用ライブラリの『DXライブラリ』は Direct X を呼び出す仕組みになっています。そして、ゲーム開発ツールのひとつであるウディタのソースコードは、DXライブラリとVisual C++ を使って書かれていると、作者が公表しています(ただしソースコードは非公開)。しかし、ウディタを用いたRPGプログラミングでは DXライブラリによるコーディングはしない。ウディタにはコード入力の機能は無く、マウス操作や、キーボード操作、キャラ名称や会話文などのテキスト文字や数値の入力のみに対応している。
===乱数===
そもそも乱数とは何かという問題があるが、それは高度な数学的な議論になるだろうから、我々はその問題には深入りできない。
ゲームにおける乱数的な処理では、事実上ランダムな値にならず、演出や調整のためにアルゴリズムが介入している場合も多い。例えばゲーム中のくじで「外れ」続くと、当たり確率が変動し、次からは当たりやすくなるアルゴリズムなども良く使われる。<ref>『ゲームプランナー集中講座』、P232</ref>。
ゲームは娯楽であり、実用目的のシミュレータではないし、アルゴリズム介入で、確率的にもいんちきが多いので、あまり厳密なランダム性が問題になることは少ないだろう<ref>『ゲームプランナー集中講座』、P231</ref>。
例えばさいころというのは典型的な乱数器だし、ゲームにもよく使う物だろう。
無印C言語には標準的乱数関数 rand()があるが、これを乱数発生に使うことに批判的な意見もあるし、機能もやや不足していると見れる。
Windows64bit では int rand(void) の出力は 32bit 整数だろう。まず stand関数で初期化してから rand()を呼ぶごとに疑似乱数が帰ってくる。これの複数回の連なりが乱数列だね。帰ってくる値は0 以上 定数RAND_MAX の値以下。
例えばさいころの数値が欲しいなら、rand の返り値を6で割った後、余りに1足せば、とりあえずそれらしいものはできる。
RAND_MAXは rand()の属性として定数が与えられているだけだから(Windowsで0x7FFF)、この値の変更はできない。
まあこれでもそこそこいい加減な乱数として機能するだろうが、最近ではもう少し改良された、質の高い乱数関数もある。
また、改良された乱数関数は、乱数の範囲も指定できるから何かと使い勝手が良いし、バグを防ぐ効果もあるのだろう。
<syntaxhighlight lang="cpp">
Random^ saikoro1=gcnew Random();// Random^ でRandomクラスの変数を作っている。gcnewはインスタンスをつくるための演算子。
int detame; detame=saikoro1->Next(1, 7);// Next メソッドで「〇〇以上△△未満」の乱数を指定できる。「->」はメンバーアクセス演算子。
MessageBox::Show("目"+detame.ToString()+"が出ました。");
</syntaxhighlight>
↑例えば上述のコードは前編集者が示したものだが、これは .NETプログラミングですね。.NET のSystem::Randomクラスを使っている。.NETのクラスは普通、C#かVisual Basic で利用するので、Visual C++で使えるようにするには結構面倒な手管がいるが、その辺は読者諸兄、ヘルプやネット情報を参照して、適宜辿り付いてほしい。
C++ の場合はむしろ、 #include <random> を宣言してそこで使える関数を使用するほうが簡単でしょうね。この場合でも、乱数としての精度も高いし、帰り値の範囲指定もできる。
===画像のちらつき===
画像がひんぱんに変化するアプリでは、画面が、ちらつく事がある。画面のちらつきは、ゲームのように、画像を凝視するアプリでは、かなり利便性を損なう。
キャラクターが1歩移動するだけで、画面全体がちらついたりする場合もあり、かなり、プレイヤーの不満になる。
これは、ダブルバッファ(「裏画面」と、良く言われる)という技術で、解決を図る。
Direct Xの用語では「スワップ チェーン」と呼んでいる。
.NET Framework開発環境の C++や C#でもダブルバッファの機能があると解説されている。いくつかのGUIオブジェクトのプロパティで、ダブルバッファの設定項目がある。
しかし前編集者が実験したところ、この機能を有効に使って確認することはできなかったとの指摘がある。ひょっとしたら何らかのマイクロソフトの解説に間違いがあって、工夫次第では利用できるかもしれないが、少なくとも今現在のこのページでは、その問題に関するリファレンスは提供できない。
そこでやはり、以前の項目と同様、Win32 API または DirextX の利用をこのページでは考えたい。
前編集者は、.NET Framework のフォームデザイナでは、ちらつき自体は解決できそうだが、グローバル変数の共有が困難だったり、アプリ内から終了コマンドが使えない、などの難点があると指摘している。
ただ現編集者はこの2点に関しては、解決策はあると思うが、しかし特に調査はしない。
前編集者は、.NETプログラムでゲームを作る難点をいくつも上げているが、おそらくどれも、.NET の仕様や全貌に精通すれば解決できるように思えるが、そもそもその全貌がかなり広大なので、解決の道のりは長いだろう。
そこで少なくともこのページでのWindowsゲームプログラミングは、Win32 API を利用したものになるだろう。
==セーブ、ロード、データベース==
=== セーブ機能とロード機能の作り方 ===
もしゲームのためにセーブ機能が必要で、単に数値(HPなどの現在値など)や文字列(プレイヤーの作成したキャラの名前など)や現在地やフラグ状況などを保存したい場合なら、普通のC言語の fopen 関数のテキストファイル書き込み機能で、簡単にセーブ機能を実装できる。
つまり、Windows API の CreateFile 関数でなくとも、標準C言語の関数でも Windows ゲーム用のセーブファイルを作成できる。具体的には、標準C言語のfopen関数でも、Windows のGUIなゲーム用のセーブファイルを作成できる。
プログラム内容も、セーブで保存したい内容を、単にテキストファイル形式で書き込めばいいだけである。
ロードも、単に、書き込んだ内容を、fopenの読み込み機能でセーブデータをゲームに読み込んで、読み込み内容に従ってゲーム中の変数に適切な数値を代入させればいいだけである。
ただし、テキストファイルでセーブを書き込んだ場合、数値などは単なるテキスト文字として保存されるので、ロードの際にはC言語のatoi関数で数値に変換する必要がある。
なお、もし機械語でセーブファイルを作りたい場合は、既存のファイル形式(画像ファイル形式や音楽ファイル形式など)の機械語の形式に機械語ファイル識別子などが、かぶらないようにする必要があるので、作成の難度がやや高い(機械語のファイル冒頭には、ファイル識別子の情報がある)。
一応、もし既存のファイル形式に識別子が重なってもC言語プログラムで読取も書き込みもできるが、あまり推奨できる設計ではない。万が一、それが原因で不具合が起きてもプログラマーの自己責任である。
なお、市販のパソコン用ゲームや同人ゲームなどだと、テキストファイルでなく機械語で保存されているゲームも多い。ゲーム開発ツール側じたいが、そうなっている場合もある。たとえば、RPGツクールもウディタも、セーブデータの形式は機械語である。なぜ分かるかというと、ツクール製ゲームのセーブデータを、なんらかのLinuxデスクトップ上でセーブファイルをオープンすると、ファイル内容がいくつもテキスト文字として認識せずにエラー報告されるからである。ウディタの場合、そもそもLinux上ではテキストエディタではオープン不可能か、なんとか開けても、やはり中身がテキスト文字として認識されずにエラー報告されるからである。
テキストファイルによる保存は、日本のゲーム業界では あまり好まれていないようだ。
なお、暗号化について、たとい機械語でセーブ内容を書き込みをしてもバイナリエディタなどで読み込めば中身を読めてしまうので、ソースコードの内容を機密にしたい場合は暗号化が必要である。
=== その後のセーブ・ロード機能の整備 ===
セーブ&ロード機能の作成のプログラミングに挑むなら、セーブから作るほうが作りやすいだろう。
しかし、最終的にセーブ用関数とロード用関数の一部を統合する場合などは、ロード機能を基準に考えたほうが良いだろう。
この理由は、まず、セーブ機能とロード機能では当然、セーブファイルの読み方の書式を統一しなければならない。(でないと、ロードの前後で、ゲーム主人公の能力値や進行状況などが変わってしまい、セーブとしての機能を果たさない。)
なので、ともかくセーブとロードにおけるセーブファイルの書式を統一する必要がある。
ロードのほうが処理が複雑であり、プログラムが複雑になるので、ロード機能を作りやすい書式なら、セーブ機能も作りやすい。つまり、ロードの都合だけしか考えていない書式であっても、比較的ラクにセーブ機能のプログラムを書ける。
一方、セーブ用を基準にして考えたセーブファイル書式は、必ずしも、ロード機能のプログラムを作成しやすいとは限らない。
では、なぜロード機能のプログラムは、複雑になりやすいのか?
まず、セーブの場合、最終的に外部に出力されたデータには、データ型の差異(int型やchar型などの差異)は無く、すべてテキスト文字列として処理されているので、プログラムは比較的に単純である。
しかしロードのほうは、読み取った文字列がint型なのかそれともchar型なのかなどの解釈をプロプラムで指示しなければならないので、よってロードのプログラムはやや複雑になる。こうして、セーブ機能よりもロード機能のほうがプログラムが複雑になりやすいのである。
== ゲーム中の特殊イベント ==
* [[ゲームプログラミング/特殊イベント]]
たとえばRPGなどでは、ゲーム中で1回しかおきない特殊なイベントとかを作りたい場合があるでしょう。RPG以外でも、シミュレーションゲームなどで特殊イベントを実装したいこともあります。たとえば、もし日本の中世の戦国時代シミュレーションゲームで「桶狭間の戦い」が3回も起きたりしたら困ります。
そういう話題について、とりあえずの叩き台的な、「こうプログラミングしたら、いいんじゃない?」的なことをリンク先では説明しています。
== スケジュール管理の教養 ==
[[File:Tokai Hairo.jpg|thumb|500px|ガントチャートの例:東海発電所の廃止解体工程]]
個人でのゲーム開発には全くの不要な知識ですが、スケジュール管理表といわれる技法がいくつかあります。
「作業責任分担表」(TRM: Task Responcibility Matrix)といわれるスケジュール表から、
それをグラフ的に図示したガントチャートといわれる表を作って、その表を見て作業計画を判断する方法です
<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
{| class="wikitable" style="float:left"
| 仕事
| 担当
| 状態
| 開始
| 終了予定
| 終了日
|-
| 仕事1
| 田中
| 済
| 2021/10/03
| 2021/10/10
| 2021/10/10
|-
| 仕事2
| 田中
| 仕掛
| 2021/10/11
| 2021/10/13
|
|-
| 仕事3
| 鈴木
| 済
| 2021/10/05
| 2021/10/08
| 2021/10/08
|-
| 仕事4
| 山田
| 未着手
| 2021/10/13
| 2021/10/17
|
|-
|}
{{-}}
ガントチャートでは普通、横軸に日程をとります。
ゲーム業界でもガントチャートの横軸は日程です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
ガントチャートとして図示することで、どこがボトルネックなどのリスク要因になりやすいのかが、一目瞭然です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
なので、それを見越して、スケジュール管理をします。
このTRMとガントチャートは、IT業界だけでなく建築工事でも使われるので、
社会人の知識のひとつとして知っておくと良いです。
ガントチャートによるボトルネックの洗い出しも、建築学の教科書でも良く教わる内容です。
よく住宅リフォーム工事などで、一般人でも建築業者の提示するガントチャートを見る機会があります。
新人の段階でそんなの書く機会はないかもしれませんが、しかし知っておくと上司からの命令が理解しやすいので、
知っておくと得でしょう。
== ストーリー作成などの順序 ==
ストーリー作りに限らず、ゲーム作りではゲーム全体を先に作るのが先決です。ニュアンスは違いますがアトラス社いわく(ゲーム開発では)、おおむね「ゲーム全体に全体に血を回すのが先」といった内容の格言があります<ref>[https://news.denfaminicogamer.jp/projectbook/191030a/2 『【ゲームの企画書】『ペルソナ3』を築き上げたのは反骨心とリスペクトだった。赤い企画書のもとに集った“愚連隊”がシリーズを生まれ変わらせるまで【橋野桂インタビュー】』2019年10月30日 11:30] 2020年12月1日に閲覧して確認.</ref>。
プレイヤーが見たいのは、ゲーム全体のストーリーやテンポといったゲームの全体像です。細部は、あくまで補助的であり、そういった細部に対するプレイヤーの興味も、あくまでオマケの範囲でしかないのです。
さて、暗黙の前提として、ゲームのストーリーは、システムと連携・調和したものでなければなりません。
このため、ゲーム作家によっては、先にシステムを決めてから、あとからストーリーを作るような方法論を採用しているクリエイターもいます<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.306</ref>。
さて、ともかくゲームのストーリー作成は、なんらかの方法で、全体像を先にきめてから、あとから細部を作っていきます。
これを実現するための方法として、いくつかの方法があります。
ドラマの脚本などで使われる、「ハコ書き」という方法を使う人もいます。全体像に当たる「大ハコ」を記述してから、「大ハコ」→「中ハコ」→「小ハコ」と記述していく方法です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.184</ref>。
そのほか、別の方法としては
:* エンディングを大まかに先に作る
:* 機能の実験を簡易でいいので事前にしておく(※プロトタイプの項目を参照)
:* 使用頻度の高い部分から作る
のような方法もあるでしょう。
そのほか、書籍『ゲームプランナー入門』で紹介されている事例だと、アルファ版(α版)を中盤から作り始めています<ref>吉冨賢介『ゲームプランナー入門』、P17</ref>。α版の製作目的の一つとして、そのゲームが本当に面白いかの検証や(駄目すぎたら製作中止)、改善するとしたらどこかの洗い出しが目的ですが、中盤だとそのゲームの全体像がわかりやすいので検証しやすいからのようです。
作品やジャンルや製作目的などによって、エンディングからか中盤からか、どこから作り始めるかは若干の違いはあるでしょうが、ともかく必ずしも冒頭部から作り始める必要がないということです。
;エンディングおよびラスボス戦闘を早めに作る場合
まず、ゲーム用のストーリー(ゲームシナリオ)の作り方ですが、学校などでの作文の書き方の順序と、ゲームシナリオの書き方の順序は、違います。
作家にもよりますが、ゲームシナリオを作る場合、エンディングを早い時期に作る人もいます<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
文献『ゲームプランとデザインの教科書』によると、シナリオでなくシステム面についても、先にゲーム全体のクリア条件を決めてから、あとから各ステージなどのクリア条件を決めていくことが多いようです<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.253</ref>。
では、シナリオの仮のエンディングについて考えていきましょう。このエンディングは、当面の仮のエンディングなので、あまり作りこむ必要がありませんが、しかしエンディングが必要です。
エンディングのシナリオと、キャラクターの性格づけの設定があることにより、そのゲームで何を主人公に目指させるべきなのかが、作者にハッキリとします<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
ともかく、方法は作家ごとに色々と違いはありますが、そのゲームの全体像を何らかの方法で決めるのが先です。
また、ゲームでは最後のラスボス戦がそのゲーム中でもっとも高負荷だったり、全部のシステムが組み合わさってたりしますので、先にエンディングを作っておくことで、そのゲームで最大負荷の状態を検証する事が出来ます<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
また、3Dゲームでは、RPGなら戦闘シーン、アクションゲームならアクションシーンが、一般的に、最も高負荷です<ref>ntny著『ローポリスーパーテクニック』、ソフトバンククリエイティブ、2010年2月16日 初版 第5刷、P28</ref>。
処理オチの確認とかも、この方法で確認できます。
また、ラスボス戦およびエンディングは、そのゲームの大きな見所のひとつであり、ほぼ最大の見所がラスボス戦およびその前後です。
いっぽう、中盤などは、比較的に重要性が下がります。
なので、スケジュール遅延や容量不足などで、ストーリーを短くしないといけなくなった時などは、ラスボス戦以外の場所を削ることになります<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
よって、ラスボス戦などは削る可能性が少ないので、先にラスボス戦を作っておけば、たとえスケジュール遅延などをしても、先に見所を作ってあるので、早くリリースしやすくなります。
{{コラム|イラストなど異分野での類似事例|
似たような、先に結末を決める事例は、イラスト技法にも存在します。
1995年ごろ、イラスト雑誌『コミッカーズ』(1995年 コミッカーズ季刊 夏号)に、当時の人気漫画家&イラストレーターの藤島康介がインタビューされたのですが(なお、その号の表紙は別の漫画家(唯 登詩樹))、
藤島はインタビューにて、おおむね内容『よく若い漫画家さんから相談で「先生みたいに女性の長い髪を書くとき、毛先を書くのが難しいです。根元は書けるのに」との相談を受けるのですが、
僕(藤島)は髪を描くときは毛先から始めて根元に向かって描いてます』みたいなインタビュー返事をしました。
こういうふうに、大切なのは頭の使いようです。要するに、ズレるのが怖い場所は、先に位置決めをすればいいのです。髪の房(フサ)の根元と毛先だったら、ごく一部の場所を除いて、読者の目線では毛先のほうが目立ちます。
だったら、作画の際の誤差は、読者には気づかれない根元の部分に押し付ければいいのです。
よくよく考えれば、イラストに限らず機械製図とかでも普通にそういう位置決めの優先指示の記法はあるのですが、
しかし世間の人は、なかなかそういう発想を異分野に応用できません。普通の人はついつい、実際の髪の伸びる順序どおりに根元から描いてしまいます。
}}
* 目標の提示
ゲーム中の目標の明確化は、シナリオの設計手法としてだけではなく、たとえば各ステージ目標の提示などは、プレイヤーをゲームに引きこむ手法にもなります。
というか、文献『ゲームプランナー入門』によると、もしゲームの目標や課題が満足に語られていないと、プレイヤーは最悪、「?」となり、コントローラーを置いてゲームを中断してしまいます。なので、設計の際、各ステージやエリアなどの冒頭で、そのステージの課題や目標などを明示する必要があります<ref>『ゲームプランナー入門』、P39</ref>。
ファミコンの古いアクションゲームだとゲーム本編では目標は語られていませんが、しかし説明書などではキチンと目標が語られており、実際にスーパーマリオブラザーズの第1作目では説明書では目標がクッパを倒してピーチ姫を救出することだと語られています<ref>『ゲームプランナー入門』、P54</ref>。
=== その他の開発順序 ===
==== チュートリアルの細部は後回し ====
:※ 特に出典は無いですが、技術系の仕事では常識的な考え方です。
RPGやシミュレーションゲームなど、プレイヤー視点では、ゲームの始めのほうに操作説明などのチュートリアルのイベントがありますが、しかし、実はチュートリアルの細部は、作るのが後回しになる場合が多々あるかと思われます。
なぜなら、ゲームで仕様を変更するたび、チュートリアルも変更の必要が生じるからです。このため、チュートリアルのとりあえずの完成の時期は、けっこう後回しになります。
よほど仕様の単純なゲームなら別ですが、そうでない場合、あまり開発初期からチュートリアルの細部を作りこみすぎないようにするほうが安全でしょう。
そもそも、チュートリアルをゲーム本編に組み込み必要もありません。たとえば説明書などで、細かい説明を代用する事だって可能なわけです。
チュートリアル部分に深刻なバグが発生してないかとか、逆に本編ゲーム中にチュートリアルが異常起動しないかなどの確認のために、開発初期からチュートリアルを組み込んでも構いません。ですが、おそらく、最終的なチュートリアルの完成時期は、仕様やゲーム全体像が本当に完成・確定したあとの時期なので、ゲーム本編の完成間近の時期になるか、もしくは本編完成後になるでしょう。
== 古典ゲームと技術限界 ==
ゲームを作る際、過去の名作ゲームを参考にしようと思うでしょうが、
しかし過去のゲームの設計は、当時の性能の限界に影響を受けているので、
果たして現代のコンピュータ性能の飛躍的に上昇した時代でも過去の設計をそのまま参考すべきかは、
やや検討の余地があるでしょう。
歌舞伎などの古典技芸の伝承の格言で『師を見るな、 師が見ているものを見よ』という教訓があると言われています。
このセクションでは、主に1980年代のファミコン時代のゲームを例に説明します。
=== スプライト ===
ファミコン時代の昔のゲーム機には、一画面に表示できるキャラチップ数(敵チップも含める)に上限がありました。
一画面中に表示できる限界は、だいたい、マリオが一画面中に数十人ぶんです。(実際の数値については、本ページでは触れない。説明の本質には関係ないので。)
ファミコンでは、このような仕組みを 「スプライト」と呼んでいました。(実はマリオ1体の表示の時点で既に、いくつかのスプライトの小単位を合成したものになっているのですが、説明やややこしくなるので、このページでは触れません。)
ともかく、実は昔のゲームのステージ設計は、スプライトの制限を前提にしたものになっています。
極端なハナシ、もしたとえばシュテイングゲームなどで、動く敵100体をボムで一瞬で倒せるようにしたゲームを設計しようとかファミコン時代に思っても、
ファミコンではすでに敵100体の表示の時点でグラフィック性能的に原理的に無理なのです。
どうしても敵100体を表示したい場合、表示のタイミングを変えます。
たとえば、
:1タイミング目では0~10体目までのAグループを表示、
:2タイミング目では11~20体目までのBグループを表示、
みたいにして、タイミングを変えることで、なんとか表示するのです。
このため、画面上に動くキャラクターが多いと、一瞬、ほかのキャラが消えるのは、裏側でこういうタイミング切り替えの処理が行われているからです。
説明の都合上、本ページではキリのいい「10体目」までと 上記の例では表現しましたが、実はファミコンの制限はもっときびしく、横1列上には8体目までしか表示できないと言われています。(しかもマリオ1体自体が、じつは2体×2体の計4体チップを使っているといわれる。なのでマリオ5体は同一ライン上には表示できない。)
なおシューテイングゲームの場合、敵チップだけでなく、敵味方の双方の弾丸もチップを利用しますので、実際の制限は上記の数値例よりも、もっと厳しいでしょう。
また、プレイヤー視点ではキャラクター1人にしか見えていなくても、背の高いキャラクターなどはキャラクター2体以上に相当するなど、注意しなければならないこともあります。
だからファミコン時代のアクションゲームで、巨大ボスのいるステージでは、ボス以外の敵が出現しないのは、おそらくですが、プレイヤー視点では1体のボスに見えても、内部プログラム的には敵チップを何体ぶんも利用しているのでしょう。
しかも巨大ボスは、ゆっくりとしか動きません。
おそらく、そのゆっくりとした時間内にVRAMを書き換え中だったのでしょう。
日本ではコトワザで「ウドの大木」みたいな言葉があるので、なんとなく巨大ボスがゆっくりと動いても不自然ではないかもしれませんが、よくよく考えたら現実世界の大男はけっこう動きが早いです。(レスラーやヘビー級ボクサーなどを考えれば分かるでしょう。)
=== 書き換え速度と背景グラ ===
ファミコンのマリオでは、書き換えの手間を省くために、一説には、たとえばマリオ1の地上ステージの世界の空の青色は、実はほとんどの場合、マリオが横スクロールしても空の青色の部分は書き換えをしておらず、横スクロールする前の青色をそのまま使いまわしていると言われています。
なぜそれで効率化できるかというと、ステージ中の障害物はほとんどのステージの場合で、画面の比較的に低い位置に障害物があるので、その低地の障害物だけを書き換えすれば済むからです。
だからファミコン時代では、こういう理由から、ステージの背景グラフィックや、障害物配置なども決まっているでしょう。
だから果たして、現代でもそれを過去の名作のステージ構成を踏襲すべきかどうかは、分かりません。もちろん、仕組みを分かった上で真似るのなら、それは特に問題ないでしょう。
=== アナログテレビの にじみ ===
ブラウン管では、細かすぎるドットは表示が、にじみます。ゲームに限らず、テレビアニメや一般の実写番組などでも同様、にじみます。(どのように、にじむかは、専門的なので説明を省略する)
だから、ファミコン時代から、だいたいプレステ1時代のゲームのグラフィッカーは、このことまで意識してドットを描いているはずです。
ともかく、液晶テレビとブラウン管テレビでは、同じ画像データでも表示結果が変わります。
レトロゲームから勉強する際は、ファミコン〜プレステ1時代のレトロゲームでは、データ上の解像度よりも実際のディスプレイ上の映像は細かいことに気をつける必要があります。
たとえば滲み(にじみ)を意図的に利用することでテレビの解像度以上の表現をしていたりしていました。
また、ファミコンのドットは縦横の長さが縦方向と横方向とで長さが違うので、そこまで考慮して、グラフィッカーは絵を描いています。
また、ドットの図形的な細かさだけでなく、色についても、にじみによって、当時のゲーム機の色用のビット数の限界を超えた表示をファミコン時代から行っていました。
つまり、同じドットの黄色の単色でも、そのドットの幅が1ドットか2ドットかで、テレビ上で表示される色が違います。「色が違って見える気がする」ではなく、実際にブラウン管のディスプレイ上では色が違うのです。言い方を変えると、ブラウン管テレビでは元の画像データ通りには色は表示されていません。(さらに縦方向と横方向とで色のにじみ方が違うが、専門的すぎるので、説明は省略する。wiki書くために調べるほうも大変なので。)
なので、もし現代の人がファミコン当時のゲーム作品のグラフィックを参考にする際は、このことに気をつける必要があります。一番、手軽なのは、そもそもグラフィックの細部については参考にしないことです。
これはつまり、もし公式エミュレーターなどでファミコン時代の古いゲームを、現代の液晶ディスプレイ用のゲーム機でプレイしても、エミュレーター側で過去テレビのグラフィック特性の再現のための特別な工夫をしてないかぎりは、実はグラフィックの表示結果が当時のものとは異なるわけです。
一方、パソコン市場では、ノートパソコンの普及し始めた1999年頃には液晶ディスプレイのものが比較的に安価で出て来たので、この頃からパソコンゲーム市場では次第にブラウン管のにじみを考える必要が無くなったでしょう。
なお、アナログテレビはそもそもテレビ自体の解像度が低いので、プレステ2時代あたりからのゲームには合いません。だから、プレステ2時代あたりからは、あまりブラウン管の特性を考える必要はなくなります。
逆に言うと、あまり指摘されないことですが、プレステ2時代の当時の人が当時の最新ゲーム機をプレイするには、もし既存のアナログテレビを使い続けていた家庭は、テレビ受像機そのものを買い換える必要があったという亊です。
一応、家電量販店などでテレビ用のアナログ/デジタル信号の変換機などを購入してテレビに接続するなどして使えば、デジタルテレビ用のゲーム機もプレイ可能ですが。
だからアナログ放送自体は2010年くらいまで続いたとはいっても、あまり当時のゲーム機をアナログ用テレビでプレイしていたとは考えにくくはあります(プレイヤーの好みによる)。
アナログ停波以降の時代である2010年以降の現代では、もうテレビ番組の受像でもブラウン管は一切用いられていないので、もはや現代のコンテンツ制作では特に考える必要はありません。
ブラウン管自体のドットの縦横が違っている。
このため、ブラウン管を前提にしたゲーム機やパソコンはそれに対応するために画像データ側のドットの縦横比が違っている。
ゲーム機やパソコンの種類、さらにはアーケードゲームの基盤といったハードウェアの種類ごとに、コンピュータ側でのドットの縦横比の管理は違っている(らしい)。このため、移植のたびに、ドットは書き直しになったようだ。
古いゲームの制作では「ドット用紙」という方眼紙のような印刷書面がある(らしい)のだが、そのドット用紙の時点で1マスの縦横比が少しだけ違い、1マスが長方形である。1ドットだけでは長方形であるのに気付かないかもしれないが、しかし「ちりも積れば山になる」ように、何十や百ドットも積み重なれば、縦横の長さは大きく違ってくる。
現在のパソコン用のドットエディタ(という画像制作ツールがある)は1ドットが正方形であるが、しかしファミコン時代は1ドットが(ドット用紙の時点で)少しだけ長方形である。(なお、画像制作ツールそのものの作り方については、『[[ゲームプログラミング/画像ファイルの作成プログラム]]』で説明する。ゲーム制作では普通は必要ないが、知識として。)
ファミコンの色数制限は52色から4色×4パレット(1パレットあたり4色)を使えると言われている<ref>[https://mynavi-creator.jp/blog/article/history-of-2dcg-designer
『2DCGデザイナーなら知っておきたい2DCGゲームの歴史』 2017/8/21 マイナビクリエイター編集部 ] 2021年12月30日に確認. </ref>。しかし実際には、4色のうち1色は透明色として利用される色であり、全パレット共通の色である(なので3×4=12色になることのいなる)。スプライトのパレットとは別に背景のパレットがあるので実際には、もっと16色以上の多くの色数が一画面内で使えるが、しかしその他のさまざまな制限があるので、合計で一画面内で25色が使えると言われる(12 × 2+1 = 25)。
しかし実際には、ブラウン管の滲み(にじみ)を利用しているので、当時のプレイヤーには1パレットだけで描かれた1キャラのキャラチップ内でも3色以上の多くの色が見えているだろうし、画面全体でも25色内にない色がプレイヤーの目には映っていることになるし、もしかしたら52色にない色がプレイヤーには見えているかもしれない。なお、スーパーファミコンの色数制限は32,768色から16色8パレットであると言われている。
レトロなゲーム機では、さらにメモリ容量やストレージ容量などの制限もあり、けっして仕様上の最大色数を気軽に利用できたわけではないだろう。こういう制限もあったからか、ネットではファミコンの色数が「4色」やら「8色」、スーパーファミコンの色数が「16色」や「256色」などとも言われることもある。
{{コラム|「ドット絵」とは|
よく世間には、ファミコン時代のゲームの、ゲーム中での絵柄のことを「ドット絵」という人がいます。プレステ1やセガサターンのポリゴンによって、「ドット絵」が無くなったと思っている人もいます。
しかし現実には、プレステ以降でも、顔ウィンドウの顔グラフィクや、キャラチップなどのグラフィックでは、その制作時にドット単位のグラフィック指定は行われています。
たとえば装備品で武器の横に小さい剣の絵などのアイコン画像が書かれている作品などもありますが、こういったアイコン画像もドット単位の指定で描くでしょう。
こう指摘すると、「プレステ1以降のゲームは解像度が高い」とかよくわからない反論をする人がいますが、しかし「ドット」という工学用語のどこにも、「解像度が低い」とかの意味はありません。また、「ドット」というのをブラウン管ディスプレイの映像だと思ってる人もいます。
しかし、液晶ノートパソコンの普及した2001年以降の液晶モニターの時代ですら、
「液晶のドット欠け」などのように「ドット」という用語は使われます。
「ドット」というのは、けっしてゲーム用語ではなく、「液晶のドット欠け」のように電子工学などですでに意味が決まっているので、ゲームオタクの戯言(ざれごと)は「ドット」の意味には無関係です。
さて、プレステ1以降のゲームでもキャラチップなどでは、ドット単位の指定が行われるのでした。
それどころか、携帯ゲームソフトでは、ガラケーの時代から既にドット単位の指定は現役の手法であり、スマホゲーム時代の現代でも現役です。
だから「ドット絵には魅力がある」とかいって、ファミコン時代のゲームばかりあげる人は、こういう現役のドット絵作家の努力が目に入らない人ですので、なるべく信用しないほうが良いと思います。
また、画像編集のフリーソフトまたはシェアウェアで、現代でも「ドット エディタ」と呼ばれる種類の画像制作ソフトがあり、少なくとも2D同人ゲームの制作ではよく使われます。
ツクールやウディタのドット絵を作る場合でも、ドットエディタを使って作るわけです。
ゲームに興味なさそうな人が「ドット絵」をレトロゲームの絵という意味で使うのは仕方ないかもしれませんが、しかしゲーム通みたいな顔して「俺ってけっこうオタクなんだぜ」みたいなフリしてるのに、レトロ的な用法で「ドット」という言葉を使う人はアレです。
おそらく、本当はけっしてドット絵が好きなんじゃなくって、単に自分の子供時代の思い出が好きなだけだと思います。
ニュアンスは違いますが、アニメ評論でもそういう話があります。1990年代後半に岡田斗司夫と誰かの対談で(おそらく書籍『マジメな話』での対談)、
「アニメの黄金期はいつか?」というよくあるアニメオタク談義について、
対談相手が言うには、
よく「70年代だ」「いや80年代だ」とかで議論が始まるが「いや12歳だ」というオチが有名だと。
}}
=== アナログテレビの焼きつきなど ===
あまりゲーム評論では指摘されないのですが、
このほか、ファミコン時代はテレビ受像機がアナログのブラウン管ディスプレイなので、
あまり長時間、同じ色をディスプレイ上の同じ位置に表示し付けていると焼きつきが起きる可能性があるので、
ステージごとにコンセプトになる背景色を変えたり、
あるいはステージの背景色を黒にしたステージを増やしたりとかの工夫も、必要だったかもしれません。
ゲームではないですがパソコンソフトなどの古いソフトは、こういったディスプレイの焼きつきの事を考えており、だからスクリーンセーバー機能の搭載など何らかの対策をしています。
ともかく、あまり、特定の色ばかり続けて使いすぎないようにする工夫が必要だったでしょう。
アナログテレビは西暦2010年のアナログ停波する時代まで使われていたので、焼きつき問題はファミコン以降のプレステ1~2時代のゲームにも関係するでしょう。
ネット上にはデマで「ブラウン管だと焼きつきが起きない」(×)というデマがあるが、しかし西暦2001年くらいの筐体パソコンのモニターはまだブラウン管が多かったし、その時代からすでに焼きつき防止のためにスクリーンセーバーがWindowsに搭載されていた。だからデマ「ブラウン管だと焼きつきが起きない」(×)にダマされないように。
なお、現代のテレビ受像機には、焼きつき防止のためにすでに「ピクセルシフト」という機能があって、
これは画面上の映像の表示位置をタイミングによって微妙にズラす機能です。こういう機能がすでに搭載されているので、わざわざゲームソフト側で実装する必要はない。そもそも液晶モニターは、焼きつきが起きにくい。ただし有機ELはどうだか、まだ新しい技術なので分からない。
== 脚注 ==
<references />
== 関連項目 ==
* [[ゲームプログラミング/コンピュータゲームの種類]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
* [[プログラミング]]
* [[w:ゲームプログミング]]
{{DEFAULTSORT:けえむふろくらみんく}}
[[Category:ゲーム]]
[[Category:情報技術]]
{{NDC|007.64}}
t72gdb6xkq056hazlu3a2g98x8rfp66
205801
205800
2022-07-24T21:58:24Z
Honooo
14373
/* セーブ機能とロード機能の作り方 */
wikitext
text/x-wiki
<div class="pathnavbox">
* {{Pathnav|ゲーム}}
* {{Pathnav|工学|情報技術|プログラミング}}
</div>
== 概観 ==
このWiki参考書では、コンピュータを用いた[[w:ゲーム]]のプログラミングを扱います。つまり、いわゆる「テレビゲーム」や、[[w:コンピュータゲーム|コンピュータゲーム]]に関する記述についてです。
ここでは家庭用のパーソナルコンピュータで扱える範囲の事柄、それらのゲームソフトをつくるためのプログラミングについて議論します。必要に応じて家庭用ゲーム機の話題にも触れますが、あくまで派生的なものです。本書はプログラミングの教材であるので、大多数の読者が最初にプログラミングで触れるであろうパーソナルコンピュータでのプログラミングを、特にことわらないかぎりは想定しています。
用語に関して、コンピューターゲームの世界独自なものもあるでしょうから、適宜『[[ゲームプログラミング/コンピュータゲームの種類]]』などを参照してください。
== 本書の目的 ==
この教科書『ゲームプログラミング』の目的は、題名にもあるとおり、プログラミングによってゲームを作るための技術の参考資料を目的としています。
ゲームクリエイターやゲームデザイナー(絵描きではなくゲームの設計者のこと)のためではなく、プログラマーのための教科書です。
したがって本書では、ゲームとは関係の少ない一般IT企業での仕事のしかたについての記述もあれば、製造業系の組込ソフトなどに関する概要的な記述もあります。
なぜなら本書はゲームクリエイターではなく、たまたま何らかの理由でゲームを作っているプログラマーのための教科書だからです。たとえゲーム会社を退職しても、他の一般IT企業に転職してもプログラマーとして応用できることなども目指して本書は書かれています。
従って、紹介する話題が、かなりIT系、テクノロジー系の話題に片寄っています。本書で紹介するクリエイター論やデザイン論は、派生的なものにすぎません。
;本書を扱う上での注意点
特にことわりのないかぎり、本書ではC言語でのプログラミングによってゲームを作りたい読書を念頭に説明しています。
だから、ゲームの生産効率性を無視してでも、本来ならRPGツクールのような開発ツールを使ったほうが早いシンプルなゲームの場合ですら、本書ではC言語または他のプログラミング言語での開発にこだわった方法を説明している場合もあります。
;その他、本書について
このページとそのサブページだけを見ていると本書は「ゲームクリエイトの教科書かな?」と捉えられるかもしれませんが、
しかしこのページとは別に本wikibooksには「[[プログラミング]]」というページがあり、そこではC言語やJavaなど代表的なプログラム言語のwiki教科書にリンクしています。ゲーム限定の話題ではないですが、プログラミングのコードについても、そちら『[[C言語]]』や『[[Java]]』やなどの教科書のほうが(実際に動作するコードの量が)充実しています。また、Visual C++ での画面出力については『[[Windows API]]』に入門的な説明があります。
本書『ゲームプログラミング』はそういったプログラミング教科書一覧の一部でもあります。C言語やWindows API の教科書では、これをどうやってゲームのプログラミングに応用すればいいか説明できないので(本wiki『[[C言語]]』はけっしてゲーム目的のページではないので)、ゲームの実際としてプログラミングの話題を切り離すために本書『ゲームプログラミング』は存在しています。
なので本書にゲームデザイン論やクリエイター論などの内容の充実は期待できません。
本書『ゲームプログラミング』は現状、プログラマー目的以外には対応できないかもしれません。もしプログラマー目的以外の無料のwiki教科書が欲しい方は、現状では、自分で本wikiに加筆するか、あるいは本書『ゲームプログラミング』とは別に新規Wiki執筆を検討していただきたい。
== ゲームを作りたいな、よし、ゲームを作ろう。でも… ==
===しかし自分の本当の目的ってゲーム作り?===
「ゲームを作りたい」と思ったのなら、まずはあまり細かい難しいことは考えず、実際に作り始めてみるのが一番いいと思います。もちろんプログラミングについてほとんど何も知らないのなら、ある程度の勉強は必要ですが、ある程度の知識があるのなら、プログラミングの技量や知識の充実を気にするよりは、実際にゲームの完成を目指してプログラムを書いてみるのが一番いいようですよ。その過程でプログラミングの学習や経験は積んでいけますしね。JavaScriptやPython、無料でプログラミングに取り組める環境も、今現在では充実しています。
しかし、ゲームをプレイするのが好きだからと言って、ゲームを作る、までが本当に自分が好きかどうか、試しに少し作ってみたら、少し考えてみるといいですね。
例えば読者の中には、「私はRPGがすき」という人も多いでしょう。
RPG が好きという事はおそらく、よくRPGの題材になる西洋ファンタジーのストーリーや世界も好きという場合が多いでしょう。そして一方で現実のコンピューターRPGで魅力的に提供される、イラストや音楽が好きという場合もあります。
実際のゲーム業界の人々も、ゲームを彩るイラストレーションや音楽がいかに重要な要素かを語っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P85</ref>。
さて、ここで問題なのですが、「ゲームを作りたい」と貴方が思っていたとして、あなたが本当に作りたいのはゲームなのか?あるいは本当はイラストが描きたかったり、音楽を作りたいのではないか?
…というのは、ゲームというのは総合的な分野ですから、イラストや音楽はその要素として確実にありますが、それ以外、プログラミングやシナリオなど、様々な創作や創造が必要で、全ての作業量はかなり多いものになるでしょう。
そしてゲーム、コンピューターゲームにはゲーム独自の世界観があって、現実や小説や映画とは違う、独特の法則に支配された世界を作る必要があります。ある意味リアリティを持たない、リアリティから外れた世界です。だから、小説のようなリアリティにこだわるなら、ゲームは不向きかもしれません。
ゲーム作り始めの時点では、これらの判断は明確でなくても勉強目的でも構いませんが、しかその内「自分は本当にゲームを作りたいのか? Yes or no?」という疑問への答えが必要になるときがくるかもしれません。
試しにゲームを作ってみて、もし自分の本当の目的がゲームでないと分かったなら、それ以外の活動に移るのも、取る道の選択肢でしょう。
;給料は安い
職業として、商売としてゲームを作る場合、ゲームプログラマーの給料は洋の東西を問わず、安い事が知られており、書籍などでも言及されています。たとえば『CAREER SKILLS ソフトウェア開発者の完全キャリアガイド』(ジョン・ソンメズ 著)という欧米人のプログラマーの書いた本には、アメリカのゲーム業界ですらハードワークの割に賃金が低い事が記載されており、もし給料の高い仕事につきたいならウォールストリート(※米国の金融ウォール街のこと)のための仕事をするべきだと書籍中で指摘しています。
日本でも同様にゲーム業界の報酬が低いことは知られており、多くのゲーム会社の伝記漫画でも、よく語られています。
アニメーション業界と比べたら、ゲーム業界のほうが報酬が高いことは事実かもしれませんが、これは実は恐ろしいことに、アニメーション業界の報酬が異常に低いだけで、アニメーション業界よりはましだけど、結局は…というのが現状でしょう。
=== 同人ゲーム以外の発表の場 ===
2001年ごろの日本はネットを活用した同人ゲーム黎明期、フリーゲーム黎明期で、実験的な時代でもあり、多くのイラスト愛好、創作者や音楽創作者がゲーム制作に手を染めていたようです。この頃、まだイラスト投稿サイトや小説投稿サイトといったものは無かったか、あったとしても小規模でマイナーなものでした。
しかし2010年のあたりから各種の投稿サイトが普及したことにより状況は変わり、むしろ現在では、小説やイラストを発表したい人はそのジャンルの投稿サイトに直接アクセスしたほうが早く、そのためゲームを通して発表するのは人によっては廻り道かもしれません。
それをわかったうえで、それでもゲーム制作に身を投じるかを考えた上で、「よし、自分はゲーム制作をしよう」と思えるなら、ゲーム制作をするのが良いでしょう。
実際、今現在の作曲家やイラストレーターは、ゲームに関わったとしても、専門家として楽曲やイラストを提供するという立場に過ぎない場合もあり、自分自身が主体になってゲーム制作をする人は、プロアマ問わず少数派のように見えます。
同人ゲームの世界でも現在は(2021年頃に記述)、プログラマー系の作者が圧倒的に多い様です。
しかし、専門外の人だからこそ、メディアミックス的な意外な視点で新しいものが作れる可能性もあるかもしれません。コピーライター、作家の糸井重里が、マザー2の企画にたずさわった例もあります。しかし、あくまで「可能性」であり、成功はけっして保証されてはいないので、読者の自己責任でお願いします。
今現在のゲーム専門学校のカリキュラムはプログラミングが主体です。CGの授業は、週に2時間程の様。一方でゲームCG、或いは、一般CGに特化した学科もある様です。
あるWikibooks編集者Aは、もしイラストを描きたいなら、イラストの世界で描くのが安全、と考えています。ゲームプログラミングについては、プログラムを書ける人は絵コンテも描けそうだし、基本的にある程度の作図的なイラストを描ける人は多いだろうから、別にプログラミングに専念しろとは思っていません。
さて、読者がゲーム制作を職業として目指すのかどうかはともかく、とりあえず、ゲーム業界の状況を知っておくのが有用でしょう。
結局商業界の状況が権威をもってその分野を支配しているのがこの社会の基本なので、趣味でも職業でも、業界周辺のことを知っておくのは得ることが多いはずです。
文献『レベルデザイン徹底指南書』では、現実世界で自分が新しいスキルを1つ覚えたら、古いスキル1つはどれか忘れる必要があることを説いています<ref>大久保磨『レベルデザイン徹底指南書』、2016年12月14日 初版 第1刷発行、P81</ref>。著者は、最初はグラフィッカーでしたが、しかしプランナーに転職したので、グラフィック関係の技能は仕事では「忘れて」しまった、という内容を述べています。ただし、比喩的に「忘れる」とは言っていますが、実際には忘却し無くなってしまったわけではなく、仕事では時間の都合により両立できないので、グラフィック関係の技能は例え話で「忘れた」、のであり、現実にはグラフィッカー時代に培った観察眼をプランナー時代の現在でも活用している、と、書籍中では述べられています。
このことは職業、あるいは技能とは一般的にそういうもの、と考えることができるでしょう。
{{コラム|漫画家大塚志郎のアドバイス|
同人ゲーム界では、ゲーム制作と、イラストまたは作曲などを一人で兼ねている作者も、ある程度は居ます。一方ネットの世界には様々な簡単に利用できるフリー素材もあるので、イラスト作画や作曲をしなくてもゲーム制作は可能ですよね。
一人でイラスト作画や作曲をしながらゲーム制作をするのはある意味マルチタレントだとも言えますが、現実にその創作をしている人たちは、かなり年長のこの分野の熟練者が多いようです。若い19歳ぐらいの頃に、それらマルチジャンルを両立するのは、一般にかなり困難なことだと思われます。
漫画家の大塚志郎は、漫画家を漫画創作の手本にするならデビュー時代を手本にするのが良い、と、漫画家向けの技法の教育漫画で語っています。
大塚は、漫画家の人生のうちで、これからデビューを目指している新人に近い境遇にあるのは、ヒット後の漫画家の生活状況ではなく、まだ無名・マイナーな時代の態度・生活だ、と描いています。成功後の熟練した漫画家より、若いデビュー直後の作家をお手本にするのがいいだろう、という主張ですよね。
さて、それでもデビュー時代から複数ジャンルの同人活動を均等に兼業する意思が硬いなら、それはそれでひとつの考え方ですが、上述のリスクを知っておく必要があるでしょう。
}}
===ゲーム業界は産業のエンジン役?===
かつてはゲーム産業が、日本のIT産業やデジタル家電産業の中心的・牽引(けんいん)役であった時代がありました。しかし、2010年以降、この考えは当てはまらなくなっています。
PlayStation2あたりまでの時代は、経済評論誌の未来予想でも、「もしかしたら今後、家庭用の据え置きゲーム機がパソコンの代替品として、家庭のリビング家電の標準品になるかもしれない」という予想があった。ゲーム産業がそのような牽引役として、経済界から期待されていました。ソニーが国産CPUをプレステ2〜3に搭載したり、WindwosのマイクロソフトがXBOXでゲーム機に参入したり、そういう時代です。
しかし2020年代の今は違います。結局、2020年代のゲーム機に使われてる技術や部品は、パソコン用の部品や技術の流用、ゲーム機のCPUも、今やインテルなどのパソコン用CPUをゲーム機でも使っています。
もはや現代は、ゲーム業界は、産業のエンジンではないようです。
ですから今現在、新しい技術に興味ある人は、ゲームにこだわらず、直接的にその技術を勉強し改良したほうが近道です。
たとえば、インターネット技術を使って何か新しい事をしたいなら、ゲームを作るよりもwebアプリやサーバーwebサービスを作るべきだし、目的のネットワーク用ソフトウェアをそのまま制作したほうが早いし確実です。
古い経済知識の先入観にとらわれず、無理にゲーム制作にこだわらないほうが、自分自身の技能やキャリアも開けていくでしょう。
2010年に出版された商学書籍『メイド・イン・ジャパンは終わるのか』には、「しかしながら、ファミリーコンピュータで世界に攻勢をかけ、その後圧倒的な強さを誇っていた日本の家庭用ゲーム産業も、90年代末からはその競争力にかげりがみえはじめた。日本の国内市場は伸び悩み、成長率は鈍化傾向にある(図表7-3)。」とあります<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.263</ref>。
その「図表7-3」の統計値によると、
:ファミコン発売の1993年には2268億円、
:スーファミ発売の1990年には2430億円、
:プレステ1発売の1994年には3882億円、
:1995年には急成長して4769億円、
:1997年には4795億円で、ほぼこの頃がピークであり、
:2000年には3768億円にまで低下(プレステ2の発売年)、
:2005年には3151億円まで低下(XBOXの発売年)、
である。(青島らが『レジャー白書』、『情報メディア白書』、『月刊トイジャーナル』、『CESAゲーム白書』などをもとに作成した図表の統計値です。)
<!-- ところで前編集者Sさん,これって正確には何の数字,金額なの?それを後で書き足しておいてほしいんだけど…。あれかな?一年のこの国のゲーム産業の売上高? -->
また、2010年の時点の商学研究では、1997年を境に、ゲームソフト市場で競争する企業数が増加傾向から減少傾向に転じた<ref name="m289">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.289</ref>、とも言われています。
書籍『メイド・イン・ジャパンは終わるのか』にも、引用文「家庭用ゲームは日本がその本格的立ち上げを主導し」<ref name="m91">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.91 </ref>と書かれているぐらいで、1990年代は日本のインパクトが強かったようです。
なお、携帯電話の分野で、日本は国際的な地位を喪失したのに対し、デジタルカメラとゲームは「現代」(参考文献の著作時2010年ごろ)でも日本が主要な地位にある<ref name="m91" />。
{{コラム|ゲームが産業の牽引役だと語った人物|
1998年頃、アニメ評論家の岡田斗司夫が、未来予想の一貫として、「これからゲーム機が、(パソコンではなく)家電の中枢になるだろう」というような内容の未来予想をしていました。たしか、岡田の著書『東大オタキングゼミ』(自由国民社、1998年)で、このような未来予想が読めます。岡田の東大での講義を加筆修正してまとめた書籍なので、実際の講義はその数年前に行われていたのだろうと思います。
岡田の東大での講義は東大生のその後の進路、官僚や大企業のビジネスマン達に大きな影響を与えただろうし、若手新進評論家として、この国の政治・経済人達も、その言論を参考にしただろう。
実際、2008年(リーマンショックあたり)くらいまでの日本の家電業界の投資は、ソニーがゲーム機のCPUを作ったりと、岡田の予想を参考にしているような面もありました。
ですが実際の2001年以降の家電業界の結果は予想とは少し外れました。まず
:* そもそも、冷蔵庫もエアコンも全然デジタル化(IoT化)されず、家電のほとんどが外部からのコンピュータ制御を必要としない状況。
:* 個々人が持ち歩いているデジタル家電は、携帯ゲーム機ではなくスマホになった。
:* パソコンは多くの家庭にいまだにインターネット用端末などとして残り続けている。
一方岡田は東大オタキングゼミで、98年当時の時点で任天堂が莫大な現金資産(たしか数千億円ほど)を持っていることに注目しています。
一般の大企業は、現金ではなく株券や不動産などの形で資産を蓄えています。しかし任天堂は、銀行口座の現金だけで数千億円という、非常に資金力の高い企業でした。今や日本を代表する世界的なゲーム大企業になっています。
また、日本だけでなくマイクロソフトのXBOXなど、実際に欧米の企業も昔はコンピュータゲームが産業の牽引役だと思って、先をこぞってゲーム機に参入していたわけでもある。岡田の未来予想は、決して根拠の無いものではなかったのです。
}}
{{コラム|読書について|
ゲーム業界と関連のない文献も、この教科書では出典として書かれていますが、これはこの頁の主要執筆者Sが、多量の市販本を読む以外に知的活動の方法を知らないことと、自分自身の文章の権威と信頼性を、著名人の威を借りて確立したいからでしょう。
ゲーム業界を志望するなら、ゲーム業界人の書いた本は少なくとも何冊かは読んでおくといいでしょう。
ネット上では、業界人ではないのにもっともらしく書かれた文章も多いですし、おそらく本Wikiの執筆者にも本格的なゲーム業界関係者は一人もいないでしょう。
業界人達のSNS発言ではなく、現代では書籍があるので、実際に書籍を手に入れて読むのがいいですね。書店で販売される書籍というのは、けっして著者だけの意見でなく、編集者や校正者、周辺の職業人達が査読をして、内容の信憑性を確認しています。
<!-- ニュース解説者の池上彰(いけがみ あきら)が、たしか2011年くらいのテレビ番組で言っていたことだと、編集者Sは言っている。 -->
何十冊も本を読むよりはプログラミングを書く実践のほうが重要でしょう。
『ゲームデザイン プロフェッショナル』著者であるFGOクリエイターも、ゲーム開発の書籍は読んでおくべきだと忠告しています<ref>『ゲームデザイン プロフェッショナル』、P234</ref>。また、ゲームデザイン本で学んだ知識は、ゲーム業界以外でも仕事術として活用できます。たとえば上司への業務報告の報告・連絡・相談(ホウ・レン・ソウ)などの考え方は、ゲーム業界でなくても活用できます<ref>『ゲームデザイン プロフェッショナル』、P332</ref>。
いっぽう、もし最新IT技術を勉強したいなら、読むべきは、ゲーム制作の解説本ではなく、そのIT技術の解説本など、そのものの書籍を読むほうが近道でしょう。
}}
===ゲームプログラミングは面白い。しかし、そんな楽な事ではない。===
ここでいう「プログラミング」とは、C言語などのプログラム言語による開発のことです。RPGツクールなど開発ツールによるゲーム制作の話は原則していません(本書『ゲームプログラミング』はあくまでプログラミングのための教科書です)。
さて、よくネットや、あるいは日常でも(C言語などによる)「ゲームプログラミングは簡単だよ。イラストやシナリオのほうが難しい。」、などという人がいますが、この発言の心は、「俺はプログラミングもイラストもシナリオも出来る凄い男だぜ。しかもプログラミングなんて簡単だし、むしろクリエイティブなイラストやシナリオの方に精力を費やす偉い奴だぜ^^」という、世間に良くいる武勇伝、自慢を語りたがる、インチキ親父が吹かしているだけなので、あまり真面目に取り合わないのが正解だと思います。
まず第一に、不当にプログラミングの価値を貶めている言説ですよね。
Visual C++またはVC# 、あるいは Direct Xなどを使ってプログラミングすることは、そんなに簡単なことではないでしょう。
ゲームプログラミングの入門書などには、初心者でも理解できそうな比較的簡単ないくつかのサンプルコードがありますが、それは初心者でも簡単に書けそうな技術だけを抜粋してるという、あくまで例外です。
RPGならたとえば、ドラクエ3のような戦争画面の行動順を処理するソート機能をつくるだけでも一苦労ですし、ほかにも道具・アイテムなどの自動整理をはじめとする標準機能を作るだけでも一苦労です。
決して上手い人のサンプルコードをコピーアンドペーストをして終わりという訳にはいかず(そもそも現状そのようなサンプルコードがネット上に無いですが)、もし仮にサンプルコードがネットに公開されていても、自作品に組み込む際にさらにそれをデバッグ(決してテストプレイの意味ではなく、実際にコード修正が必要になります)しなければならず、プログラミング言語の理解が必要です。
ゲームのプログラミングは決して楽ではないし、仮にもし楽だとしたら、じゃあゲーム会社のプログラマー職の人の仕事は何なんだ・・・という疑問につながりますよね(デマを言ってる人は、この疑問を脳内に都合よく無視しますが)。
ツクールやエディタのような制作ツールを使えば、C言語的なプログラミングは不要ですが、それはそのツクールなどのツールを開発している人達にプログラミングを肩代わりしてもらっているだけなので、決して「ゲームプログラミングが楽」、ではないでしょう。楽だというなら、じゃあツクール開発元の角川書店およびその発注先ソフトメーカーのプログラミングが楽だとでも言うのか・・・(デマを言ってる人はこの疑問を無視します)。
そもそもコンピューターゲームというのはプログラミングがなければ成立しないのですから、そのプログラミングの価値を貶めて平気な人は、コンピューターゲームにかかわる資格はないでしょう。
== ゲーム制作に関する留意点 ==
=== IT的な留意点 ===
====プログラミングなしでも同人ゲームを作れる====
自分でゲームを作る際、必ずしも、C言語などプログラム言語で記述する必要はありません。
プログラミングをせずに、ほぼマウス操作と会話メッセージなどの文章のキーボード入力だけでゲーム開発をできるようにするソフトウェアが、有料または無料で発表されています。
たとえば、RPGを作りたいなら、日本で発表されているソフトでは、『[[w:RPGツクール]]』や『[[w:WOLF RPGエディター]]』などのように、RPG製作に特化された開発ソフトがあり、大幅に開発の手間を減らせます。なお、『RPGツクール』は有料製品です。『WOLF RPGエディター』は無料ソフトです。
アクションゲームを作りたいなら、『[[w:アクションゲームツクール]]』があります。これらツクール製品は有料製品です。(なお、かつて『[[w: 2D格闘ツクール2nd.]]』というのがありましたが、しかし現在ではサポート切れのため、今現在の市販の十字キーコントローラーが初期設定では動かない、一部のボタンしか使えないなど問題点があります。)
また、ノベルゲームを作りたいなら、フリーソフトの『[[w:吉里吉里Z]]』などがあります。吉里吉里Zはソースコードが公開されており、オープンソースになっています。
:なお、とりあえず「ゲーム開発ツール」と呼びましたが、じつは呼び方は特に決まってはいません。「ゲーム制作ツール」と呼ぶ場合もあります。ゲーム開発ツールのことを「ゲームエンジン」と言う場合もありますが、開発ツール以外のゲーム用ランタイムのことも「ゲームエンジン」という場合があります。
:本Wikibooksでは、とりあえず、ツクールや吉里吉里シリーズやウディタ(WOLF RPGエディター)などのソフトの呼び方は、まとめて「ゲーム開発ツール」または「ゲーム開発ソフト」と呼ぶことにします。
C言語などによるプログラムは、上記のゲーム開発ツールを使わない場合の選択肢になるでしょう。
既存のゲーム開発ツールの仕様に不満を感じる場合に、「じゃあ自分でプログラムして作ろう」となり、プログラミングが必要になるわけです。
なお、上記の開発ツールはほとんどがWindows用のソフトです。MacやLinuxでは動きません。MacやLinuxで動作するゲームを作りたい場合は、別のソフトウエアを使う必要があります。
既存のゲーム開発ソフトを使わずにプログラムを組んでゲームを自作する場合、必ずしも既存のツールのような、ゲーム作品と開発ツールが分離された仕組みを再現する必要はありません。
一般的に初心者が、ゲーム開発ツールを作ることはほぼ不可能です。初心者は開発ツールを作ることは考えずに、まず1本、とりあえずゲーム自体を完成させてみましょう。開発ツールを自作したいのなら、まず先にゲーム1本を完成させたあとに、あとから開発ツールとゲーム作品の分離などに取り掛かるのが推奨です。
==== 商業ゲームの開発言語 ====
基本的に、現代の商業ゲームは、C言語で開発をする。
ただし、ファミコンの古いゲームは、アセンブラで開発されていた。ファミリーコンピューターからスーパーファミコンに至るまで、OSは搭載されていない<ref name="m289" />。
ではいつからC言語がゲーム開発に使われるようになったかというと、商学の学説では、プレイステーション(※ おそらくプレステ1?)の頃からだろう、と考えられている<ref name="m289" />。ただしこの時代でも、処理速度の高速化のためにアセンブラにアクセスする開発チームも少なくなかった<ref name="m289" />。
また、プレイステーションのOSは独自仕様である<ref name="m289" />。
カプコンなど一部の企業は、OSによる開発ではなく、移植性を高めるために自社製の内製フレームワークを用いて開発する。カプコンの場合、2010年頃は「MTフレームワーク」という自社製フレームワークを用いて開発を行っていた<ref name="m289" />。
{{コラム|ゲーム用のメーカー独自プログラミング言語について|
ゲーム開発ソフトには、ゲーム開発用の独自のプログラミング言語を持っている場合があります。このような機能の実現方法は、原理的には、ファイル入出力の関数を使い、テキストファイルの文字列を読み取って、文ごとにプログラム動作を設定・実行している、と、考えられます。インタプリタは、このような方法で作られています。
ゲーム製作ソフトでの独自のプログラミング言語はたいてい、コンパイル作業を必要としないので、おそらくインタプリタ方式でしょう。
基本的にWindowsの場合、実行ファイルに変換するには、Visual Studio というマイクロソフト社の配布している開発環境が必要です。
Visual Studio が開発環境を提供していない独自言語は、たいてい、インタプリタ方式となると思われます。
コンパイラ方式に比べて、インタプリタは処理速度が不利なので、適用できるジャンルや用途が限られます。たとえば3Dアクションゲームには、インタプリタ方式は不向きでしょう。
これらの独自言語を使うにしても、自分自身で独自言語を作りたいと思うとしても、この教本ではまず、既存のプログラミング言語を使ってゲーム制作を開始することを推奨します。
}}
====ゲームのプログラム言語の歴史====
ゲームを書くために利用される言語は多岐にわたっています。歴史的にはゲーム業界でも、[[C言語]]や、特に計算機のスピードが重要になる場面では[[w:アセンブリ言語|アセンブラ]]を利用してプログラミングを行うことが普通に行われていました。<!-- (文献)→-->そのため、ゲームプログラミングは通常のプログラミングと違った技能が必要であるように思われていました。
現在では計算機がある程度速くなったことや、ゲームプログラムの開発を複数人で行うことでテクニカルなプログラミングが避けられるようになったことにより、ゲームプログラミングは他の一般のプログラミングと同じような課題だと見なされています。
しかし、特にアクションゲームなどのリアルタイムでの画面書き換えが必要なゲームで、プログラムのスピードが重視されることは変わっていません。また、コンピュータの性能があがるにつれ、それらの性能を全て引き出すように表現手段が変化してきたため([[w:3次元コンピュータグラフィックス|3D]]、[[w:ポリゴン|ポリゴン]]などを参照)、状況によっては複雑で特殊なプログラミングが必要になることもあります。
===== 初心者が使えるプログラミング言語 =====
ゲーム開発において、一般にゲームショップなどで流通している商業ゲーム作品において、現在よく利用されているプログラミング言語として、[[C言語]]、[[CPlusPlus|C++]]、[[Java]]があげられます。
Windowsの3DエンジンのDirectXは、主にC++を想定しています。なので負荷の高いアクションゲームを作りたい場合、Visual C++での開発が安全でしょう。
しかし、ネット上のフリーゲームでは、C++以外の言語が使われることも、よくあります。
さいきんゲームエンジンとして有名なUnityは、言語としてはC#の文法を採用しています。
[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
市販の書籍では、Pythonによるゲーム開発を紹介した出版物もあります。ただし Python は原理的にインタプリタ方式であるために処理速度がC++に劣り、アクションゲームなど負荷の高いゲームを作る事を目指している場合は、将来的にはPythonからC++への装備変更が必要になるかもしれません。
===== ゲームに適さない(だろう)言語 =====
;Flash関係
例えば、かつて Adobe の Flash が、ブラウザで動かせるゲームを作る際に、よく使われていました。このようなwebブラウザ上で動くゲームのことを一般に、「ブラウザゲーム」と言います。ただし、現在ではFlashは廃止の方向です、すでにほぼ廃止されているといっていいでしょう。また、現状では、ローカルPC環境でのゲームをJavaScriptで作るのは、アマチュア段階では困難です。JavaScriptのアマチュアゲームと言う事例を聞きません。
;JavaScript
なお、JavaScript はクロスプラットフォームですが、しかし、セキュリティ上の理由などから、いくつかの機能(たとえばファイル入出力)がwebブラウザ上では使えないようになっており、そのため、JavaScript だけでゲームを作るのは、初歩的なゲームを除くと、かなり困難です。(おそらく、オンラインゲームでは、サーバー側でPHPやサーバサイドJavaScriptなどの別プログラムが走っていると思われます。)
セーブ機能の必要なゲームを作る場合は、JavaScriptでの開発は選択肢にない(セーブの実装には、JavaScript国際規格にはない非標準仕様を使いこなす必要があり、かなりの技術力を要するでしょう)。
=====ブラウザゲームの初歩的な原理=====
商品として流通するようなゲームや、高度な機能を持つブラウザゲームを作ることはとても難しく、このページでは手に負えません。そこで、このページでは、初心者が練習用につくるゲームを例に記述します。
webブラウザだけで動くのがブラウザゲームです。ブラウザゲームを作るのに使う言語の第一選択肢はJavaScriptです。サーバー側の処理が必要ならPHP,Python,Perl,Javaなどの言語の出番でしょう。
「ネットワークゲーム」は「ブラウザゲーム」とは意味が違います。
「ブラウザゲーム」は、パソコンにwebブラウザさえあれば、ネットワークに接続していなくてもゲームプレイできて、最後、クリアまでプレイできる作品もあります。
しかしネットゲームは、ネットワークに接続しないと、ゲームを開始することさえ不可能です。つまり、サーバの提供するゲームが「ネットワークゲーム」「ネトゲ」です。
もしPHPやPerlなどでゲームを作る場合、普通はネットゲームになる筈なので、作者がサーバを構築して提供する必要がありますし、プレイヤーにはゲーム中にサーバに接続する環境が必要になります。提供者は、サーバを用意したり、保守管理する必要がありますよね。サーバーがダウンしてしまうと、プレイヤーがゲームをできなくなります。
「PHP ゲーム」などの単語でネット検索したり、あるいは書店でプログラム言語の書籍や解説サイトを見ると、ときどきPHP・Perlなどの言語でゲーム開発しているものもありますが、一般的なダウンロード型のゲームとは違う筈なので、気をつけてください。
{{コラム|ソケット通信、ほか|
コンピュータプログラムからインターネットに通信するには、いくつかの方法がある。
C言語の場合はOSの提供するソケット通信といわれる機能を使う方法、
JavaScriptにあるHTTP通信の機能を使う方法、
などがあるだろう。
ただし、JavaScriptでゲームを制作するのは、セキュリティ上の制約などからセーブロードが標準的方法では困難など、とても制作が難しい。
よって本セクションでは、C言語にソケット通信を組み込むことの概要を説明する。
ゲーム制作初心者がソケット通信までする必要はないが、将来的には知る必要があるかもしれない。
本wikiではWindowsの場合については 教科書『[[WinSock]]』、
macやLinux / Unix や BSD の場合は 教科書『[[Unixソケットプログラミング]]』 で説明している。
Windowsとそれ以外のOSとで、ソケット通信の仕様が微妙に異なる。
ソケット通信では文字コードの問題がある。手元のパソコンの文字コード設定は、通信相手方の端末には反映されない。
Windowsの日本語版では、伝統的に Shift-JIS といわれる文字コードが使われてきたが、海外のWindows端末は日本の文字コードにあわせてくれないし、macやLinuxやBSDも同様に日本には合わせてくれない。
簡単な対処法として、ゲーム中では日本語を送受信しない、つまり半角の英数字と記号だけを送受信する、という道はある。
会員登録などのためにどうしても氏名や住所などの日本語を使う必要がある場合、PHP・Pythonなどサーバ言語に対応した「フレームワーク」があり、そのフレームワークが最初から日本語に対応、もしくは設定を少しいじるだけで日本語対応するので、それを利用すれば効率的かもしれない。
ゲームとは別途、サーバー側にフレームワークをインストールして、会員登録時にサーバー側でそれを使うようにすればいいだろう。
しかしゲーム内では日本語の扱いは非常に難しい、限定されるという事になるだろう。
C言語のプログラムにサーバサイドの言語・システムを組み込むのは難しいから、ネットゲームではどこかでソケット通信に頼ることになるだろう。
市販の本を探しても、そもそもソケット通信の書籍自体がめったに見当たらないし(ほんの少しだけ出版されている)、もし見つけても全く文字コードの問題の解決方法は紹介されていない(2021年現在)。
}}
====プラットフォ-ム====
;ライセンス料
一般に、プレイステーションや任天堂のゲームを開発するには、専用の機材が必要であり、そのため、ソニーや任天堂とライセンス契約しなければいけない<ref>『ゲームプランとデザインの教科書』、P.107 </ref>。
その契約に際して、ライセンス費用または料金と呼ばれるものを、ゲーム機開発会社の任天堂、ソニーに支払う必要があります。
現在でもソニーや任天堂のゲーム機用のソフト開発・販売には、ライセンス料が必要です。少なくともPS4やニンテンドースイッチのパッケージソフト開発には、「ライセンス費」が必要<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.120</ref>。
なお、書籍『ゲームプランナーの新しい教科書』によると任天堂やソニーのようにゲーム機を作っている会社のことをハードメーカーと言います。つまり、ゲーム機のハードメーカーにライセンス料を支払うという仕組みになっています<ref>『ゲームプランナーの新しい教科書』、P20</ref>。
また、スマートフォン向けアプリは、プラットフォーム使用料が掛かります。
書籍『ゲームプランとデザインの教科書』によると AppleStore, GooglePlayともに売上げの30%とのこと<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.121</ref>。その他のプラットフォームも、大体同じとのことです(参考文献の著作の時点では)。
Google やAppleのようにプラットフォームを提供している企業のことをプラットフォーマーと言います<ref name="gp244">吉冨賢介『ゲームプランナー入門』、P244</ref>。
昔からゲーム機のライセンス料は有料で高額であり、ソニーや任天堂の収益源のひとつになっている<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.267 </ref>。一方、パソコンゲームにはライセンス料が無いのが普通です<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.283 </ref>。
なお、ハードメーカーでなければプラットフォーマーでもないゲーム会社のうち、製造から販売までを手がける会社のことをパブリッシャーといい、たとえばカプコンやコナミやセガやスクウェア・エニックスやバンダイナムコなどがパブリッシャーです<ref name="gp244" />。
実は、必ずしもパブリッシャーが開発を手がけるとは限らず、スマホ向けアプリなどではディベロッパーといわれる開発専門の会社に委託している場合もあります<ref>吉冨賢介『ゲームプランナー入門』、P245</ref>。
;ポリコレ規制
Apple社のAppStore向けのスマートフォンアプリでは、アップロード後に、公開前にAppleによる審査があり<ref name="g139">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.139</ref>。、審査は欧米基準です。
GooglePlayは、公開前の審査はないが公開開始後に海外基準で審査されるので、それに違反していると配信停止になります<ref name="g139" />。
海外プラットフォームで販売・配布したい場合、「ポリティカル・コレクトネス」(政治的な正しさ)といわれる、海外の公序良俗の基準に配慮する必要があります<ref>『ゲーム作りの発想法と企画書のつくりかた』、P.235</ref>。
欧米の判断基準が、アジア諸国やアフリカの生活習俗に合致しない場合も多いのですが、欧米のIT大企業はその欧米基準での規制が政治的に正しいと考えているでしょう。「日本では、少し考え方が違う」と言っても、通用せず規制される場合も多い。
ゲームだけでなくテレビアニメでも、漫画ワンピースの海外アニメ版では、主人公側の若者がタバコを吸っているシーンをアメ玉に作画を変えられたり、ドラゴンボールに出てくるミスターポポという肌の真っ黒なキャラクターの肌を青く書き換えたり、色々な例があります。
ポリコレとは関係ない事例ですが、TVアニメーションのポケットモンスターで主人公のサトシ達がお握りを食べているシーンで、アメリカ版ではドーナツになっていたことがあります。これは、国による食文化の違いを示していますよね。
===プロトタイプ===
ゲームでは、曲や絵が良くても、ゲームとしては今ひとつ面白くない、という事は起こり得ますよね。
ですからむしろ、商業的なゲーム制作では、イラストは簡略なものを使ったうえで、プログラム中心の試作品(プロトタイプ)をいくつか作り、その中でゲームとしての面白さがあるものを、取捨選択したうえで商品化を考え、その後イラストや楽曲を詰めて完成度を高めていく、と、いう制作過程を取るようです。
書籍『ゲームプランナー入門』(吉冨賢介 著)によると、商業ゲーム界では、企画書に書かれたゲームが本当に面白いかどうか確認するために、「プロトタイプ」が作られます。プロトタイプの段階では、プログラマーと、企画の意図を考慮するためプランナーも関わります。<ref name="gp17">吉冨賢介『ゲームプランナー入門』、P17</ref>
イラストレーターは、プロトタイプの前段階あたりでイメージイラストを提供し、スタッフ間の共有イメージを作ります<ref name="gp18">吉冨賢介『ゲームプランナー入門』、P18</ref>。そしてプロトタイプ進行中は、グラフィック案の提案をしていきます<ref name="gcw56">蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P56</ref>。サウンドも同様、プロトタイプでは、曲調を固めていく段階です<ref name="gcw56" />。
:※時々あるトラブルとして、マイナーな同人ゲームや零細メーカーのゲームで、背景イラストや脇役キャラクターなど目立たない部分で他社のイラストが使われていることがあるようです。おそらく試作用に流用したイラストが、そのまま製品に混入したのでしょう。こういうトラブルがあるので、他社イラストの使用は試作であっても避けるべきです。
;実装検証
プログラマーは、そのゲームでコアになるプログラムやシステムやミドルウェアについて、プロトタイプ段階で実装検証を済ませておく必要があります。プロトタイプより前の原案の段階では、利用するミドルウェアの洗い出しをして、出来る範囲での基礎実験をしておきます<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P54</ref>。
ミドルウェアによっては使用料が発生するので、その点を事前に調べておく<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P55</ref>。
プロトタイプのうち、張りぼての例えば画面だけの物等を、「モックアップ」といいます。一方である程度遊べる状態まで作っているものを、「プレアブル」といいます<ref>STUDIO SHIN『ゲームプランナーの新しい教科書』、翔泳社、2018年3月10日初版第2刷、P251の図</ref>。
ゲームデザイン本ではよく「プロトタイプ」という表現が用いられるので、本ページではこの言葉を使うことにします。
{{コラム|商標権等|
知的財産権には著作権・商標権・意匠権などがありますが、商標権は特に強い権利であり、気を配る必要があります。
意匠権とは、建物や工業製品の外観に関する権利なので、ゲーム制作ではあまり気にする必要はないようです<ref name="gpd135">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.135</ref>。
「特許権・実用新案権」と「商標権」は、事業者によって国に登録されている権利で、かなり強力な権利なので、気をつける必要があります。
特許権や実用新案権とは、大まかに言えば、技術的な発明に関する権利です。商標が登録されているかどうかは、特許庁の『特許情報プラットフォーム』というwebサイト<ref name="gpd134">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.134</ref>で確認できます。
商標をトリッキーな意図で登録する人も多く、自社でビジネス展開をする気がなかったり、他社の商品などでまだ登録されていない物を申請したり、そういうやや不正な登録申請でも認可されてしまう場合も多いです。
また、商標は業種のジャンルごとに分かれているので、たとえば携帯電話のジャンルが新たに追加された時代に、過去のゲームの商標を登録した人がいました。そのため携帯ゲームを出せなかったり、商標を買い戻したり、取り戻すための裁判をするのに時間とお金がかかってしまったり、様々な問題が発生します。<ref name="gpd134" />
著作権は、登録の必要がなく、著作をした時点で発生する権利です。
『ゲームプランとデザインの教科書』によると、こういう事柄にまだ慣れていない人によくあることなのですが、他人の個人サイトやSNSで公開されていた絵や曲などを、許可なく勝手に使う事例があるようです<ref name="gpd135" />。
二次利用を許可されてない著作物は素材として使えません。
そして見落としがちなのが、フォントの著作権です<ref name="gpd135" />。フォントにも著作権があります。
フリー素材と書かれていても、商用販売が禁止されている配布形態のものもありますので、気をつけましょう。
}}
{{コラム|アイデアの権利。アイデアとは盗まれるのか、盗むのか?|
商業ゲーム作家たちの、2022/1時点でのSNS発言によると、業界全体でみられることですが、会社外部の人がアイデアを一方的に投稿してきて、会社で作った作品にそのアイデアと類似点があったら、アイデア使用料を要求してくる、そのような問題に悩まされているようです。
そこでゲーム会社側では原則、
:送られてきたハガキやメールは、まずクリエイター以外の事務系の人間が読む。
:もしハガキなどにアイデアがあった場合、そのハガキを処分。
などの方策を取ると言われています。
また、偶然や何らかの理由でアイデアが一致してしまった場合に備えてのリスク回避として、事前に会社のウェブサイトなどで「弊社にアイデアが送られてきた場合、そのアイデアは弊社のものになります」のような宣言をしている会社も多くあると言われています。<!-- (以上、作家のSNS発言やそれを紹介したサイトの取材などのまとめ.)←出典を消すなってS氏はやたら云うんだけど,そんな重要な事かね?もちろん全くなくて,いい加減な事書いていいと言ってるわけではないけど… -->
ここで前編集者は娯楽産業の世界には厄介な消費者がいると言及しているけど、この前編集者自身がこのWikibooks で異常なまでに厄介な参加者なんだが、そろそろ人のふり見て自分を返り見るべきだと思うな。
法学的には、著作権法はアイデアを保護しません(『アイデア・表現の二分論』と言います)。
そして前編集者はアイデアに関して権利をどうこう言う人間を無知だと書いているけど、自分は至上の賢人だと思ってるようだね。
そしてこの人物は他者を愚弄する時は必ず自分の意見ではなく、権威ある人がそう書いたから、出典だからと宣う。
出典は岡田斗司夫氏の著作『東大オタク学講座』や『マジメな話』だそうだ。
まあ岡田氏ならかなり過激なことを書くのは事実だろうが,この前編集者S はその悪徳をさらに10倍に高めてこのWikibooks に記述する地獄のように厄介で無知で馬鹿な人間だ。
}}
任天堂『ゼルダの伝説 ブレス オブ ザ ワイルド』は、プロトタイプの段階ではイラストや音楽を組み込まずに(イラストは、代わりに大きなドットの塊などで代用する)作られている事がゲーム業界見本市イベント CEDEC 2017 で公開されています<ref>https://game.watch.impress.co.jp/docs/news/1078888.html 2020年11月25日に閲覧して確認</ref>。
プロトタイプの段階では、画像や音楽は発注せず、骨組み的なプログラムだけで、そのゲームのアイデアが「はたして本当に面白いか?」を、実際に社内の関係者にプレイさせてみて確認します。
因みにプロトタイプに関しては『[[高等学校情報/その他の技術的な話題#プロトタイプ開発]]』の記述も参考になる。
ここでいう「プロトタイプ」(試作品)とは、コンピュータプログラムのゲームとして動作するのが前提です。映画製作でいう絵コンテ試写のように、ゲームの試作では、なるべく早期に第三者が試作ゲームを遊べるように作っていく必要があります。
プロトタイプという言葉を使用すること自体が妥当かどうか。まず、書籍『ゲームプランとデザインの教科書』で使われている<ref name="gpd350">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.350</ref>。
ニコニコ動画の経営者、川上量生が使っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日 第1刷発行、P.38</ref>。川上は角川書店も買収したので、おそらくそこ(カドカワ・RPGツクール販売元)でも使っているでしょう。
ゲームのプロトタイプの基本姿勢は、「汚く作って、やりなおす」です<ref name="gpd350" />。もちろん最低限のプログラムの知識、勉強は必要ですが、あまり知識収集や理解充実を気にするより、実際に作ってみることを優先したほうがいいようです。チーム制作をしている場合はプロタイプは赤ん坊であり、そのチームで育てていこう、我々の子供だという意識で接しているようです<ref name="gpd350" />。
勉強に関しては、汚くてもいいからまず工夫して作ってみると、何を勉強すればいいかが見えてきます。
英語では「quick and dirty prototype」という言葉があります<ref>川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.349</ref>。
書籍『ゲーム作りの発想法と企画書のつくりかた』によると、シナリオライター志望者が企画書やシナリオ案をメーカーに送りつけても、あまり効果的ではないようです。
それよりゲーム形式でシナリオを書いてしまうのがいいようで、「CHR:ヒロインA(私服)、表示」のような文章を織り交ぜて構成していくのが推奨<ref>『ゲーム作りの発想法と企画書のつくりかた、P.140</ref>。
参考文献のその章では、シナリオライター志望者に向けて語られていますが、プログラマーを目指すならどうすればいいでしょうかね。
プログラマー志望なら、サンプルゲーム、サンプルプログラムを作ってしまうのがいいかもしれません。
1990年代、週刊少年マガジンに不定期掲載していた読みきり漫画『ゲームクリエイター列伝』では、カプコン社のゲーム『バイオハザード』を扱った『バイオハザードを創った男達』の際、制作過程でゲームデザイナーが大幅な作り直しを判断して進行させた、という描写があります。(ただしWikiboooks一編集者の記憶、詳細はあいまい)。
のちの、ゲーム評論家の阿部広樹の評によると、むしろそれは劇的な大きな決断ではなく、ゲームデザイナーの日常の普通の仕事ではないか、と語られています。
どんな肩書の人間だろうと、すでに決まって進行していた方針をひっくり返すのは、かなりのストレスのある判断で指摘になりますが、一般に漫画や映画、あるいはNHKの仕事に関するドキュメンタリーでもそうですが、職業や職業者の物語では、過剰に対象を美化し、劇的な演出によって関係者を称賛し、英雄視する傾向があるように思います。
{{コラム|アイデアはアイデアで価値がある。でも、せっかくなら、それを試作して、形にしてみよう。|
ゲーム業界人広井王子は書籍のインタビューで、自分の社長としての人材評価は「0点」から始まる「加点法」だと語っていたようです。
『ゲームデザイン プロフェッショナル』著者も、文脈は違いますが「加点方式で物事を考える」と述べています<ref>『ゲームデザイン プロフェッショナル』、P224</ref>。
正直インチキなゲーム業界人の点数勘定などには全く興味ないが、そんな話とは全く別に、ゲーム制作の上で、実際に動く簡単なプロトタイプを作ってみることは間違いなく有意義な事でしょう。
アイデアはアイデアとして、思考や思想の展開としてありますが、それを具体的な形にしてみることは非常に楽しくエキサイティングで、意味ある活動ですよね。
}}
仕様書や設定資料を超えて、誰もが遊べる試作品は、意味のある企画行為でしょう。前編集者は、時間軸・動きの制作意図の明確化、という言葉を使っています。もちろん短くまとめること自体もなかなか難しいのですが、工夫を凝らして、ゲームプログラムを完成させることが重要な経験であり、思考の具体化でもあると思います。
===アルファ版===
アルファ版はプロトタイプとは違うもので、その後段階で、ゲームの全体像が分かる一部分を、商品に準じた形で作ることです<ref name="gp17" />。
アルファ版でもそのゲームが本当に面白いかどうか検証がなされます。サウンドやビジュアルは商品に近いほぼ完成化された形で取り込みます。
アルファ版の使用の結果、プロジェクト中止の決定がなされる場合もあります<ref name="gp18" />。
ベータ版とは、会社によって意味が多少違いますが(たとえば『ゲームデザインプロフェッショナル』と『ゲームプランナ-入門』とでも微妙に違う)、おおむね、とりあえずのゲーム、最初からエンディングまでのほぼ完成状態をひととおり遊べる制作物です<ref>『ゲームデザインプロフェッショナル』、P170</ref>。
細かいバグ修正はこれらの段階では後回しにします。
基本的に
:プロトタイプ→アルファ版→ベータ版→調整→デバッグ
の流れですね。
===プロトタイプ制作に必要な予備知識===
====数学は後回し====
ゲーム制作の作り始めにおいて、必要な数学や物理の予備知識は、それほど多くありません。
文献『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』によれば、数学や物理の習熟に拘って、それに多くの時間と精力を費やして勉強するよりは、3Dの勉強などで必要を感じたら、そのつど、その分野の数学や物理を学ぶのが効率的だと述べており、また可能なら実際にプログラミングでその理論を試してみると具体的に理解をしやすいと述べています<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P88</ref>。
====C言語の予備知識は入門書1冊+αで十分====
C言語を使ったゲームは、予備知識はそれほど多くないので、あまり難しいことは考えず、まず実際にプログラムを書いて作ってしまう事優先にするのが正解なようです。
市販のC言語入門書で、配列や関数などの一般的な機能を一通り習得したら、あとはVisual C++ で映像出力とキーボ-ド入力のみを、1~2週間ほど勉強、そしてVisual Studioを起動してゲームを作り始める。
うまくいけば数か月以内に、パソコン用の非ネット通信のゲームを作ることができるでしょう。
ただ、ゲームプログラミングを試みる人は、必ずしもゲーム制作のみが絶対的な唯一の目標ではない可能性もあるので、それぞれの立場に応じて、座学を取り入れてみるのもいいと思います。
== 作業リストを作る ==
===作業リストの制作開始の方法===
さて、ゲームを作る時は、アイデアを頭の中だけに置いておくのではなく、文章に書きだしてみましょう。
そして、壮大な長大なアイデアではなく、1週間~1ヶ月ていどで成果の確認できそうなアイデアだけを書いてみましょう。
次にそのアイデアを、実際に動作するプログラム、ソフトウェア(つまりプロトタイプ)にするために、具体的などんな機能を持ったプログラム(簡単なものでよい)を制作しなければいけないか、自分のやるべきことのリストを、箇条書きで作ります。<ref>https://www.youtube.com/watch?v=J5FCZG7dfEY 2020年3月17日に閲覧</ref>
IT界ではこういうリストを「ToDoリスト」(読み: トゥードゥーリスト)とか「タスクリスト」といいます。このページではむしろ日本語で、「作業リスト」と呼んでみましょう。
さて、このリストを作るときは、作業項目は具体的かつ単純な目標に分割します。ですから例えば RPG の戦闘システムを作るときは、
*「戦闘システムを作る。」
と、あいまいに総体的に書くのではなく、具体的に、
*戦闘画面のメッセージ表示欄および標準メッセージを作る。
*「戦う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは後回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
という風に、作業項目を細かく分割していきます。
こうすることで、作業がひとつずつ比較的に簡単な要素に分解されていくので、楽になります。また、バージョン管理ソフトを使って管理している場合も、上記のような作業リストの分解をしておけば、各バージョンの概要を書く際にも作業リストの項目が転用できるので、一石二鳥です。
予定日は書かないほうがいいように思われます。スケジュールを管理したい場合は、別にファイルを作るといいですね。
そして書き出した項目を優先順位で並べたら、最初の作業リストは完成です。
===作業リストの更新===
プログラミングする前に作業リストを眺めて、そして上の項目から実際に作業を開始しましょう。
そして一つの項目を完成させましょう。
そして作業項目がひとつ終わったら、「【完了!】」等、そういう情報を、項目の前または後ろにつけます。備忘のための記録ですね。
たとえば、
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
こうします。
以前の記述を残したまま、その作業が終了したことを示しておくわけですね。
また、もし追加の作業が必要になったら、たとえばダメージ計算システムを作るために、ランダム計算が必要になって、自分がそのプログラム言語でのランダム計算に詳しくないなら、たとえば
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
::※3行目に追加されています。
と、必要に応じて項目を追加します。
さて、これから行う作業を検索しやすくするため、たとえば
'''やることリスト'''
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
'''完了した作業'''
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
の様に完了した項目を後回しにしたり、或いは
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*(現在→) Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
のように、(現在→)、を追加するのも良いでしょう。
つまり作業の記述をそのままに、どこまで進展しているかが分かる等に書き足していくわけですね。
==プロトタイプ制作における創作面の検討事項==
===ゲーム性===
「ゲーム性」という概念があって、これがあるからこそゲームは面白く、魅力的だと考えられています。
プレイステーション開発元のソニーもこれを重視していますし、一般的に多くのゲーム愛好者、関係者たちもその考えに同意するでしょう。
ではゲーム性とは何か?
ゲームのジャンルにもよりますが、「駆け引き」や「戦術」、これが「ゲーム性」だとよく言われます。
『ゲームプランとデザインの教科書』によると、ゲーム性とは、シューティングやアクションでは「対戦の駆け引き」、RPGでは「戦闘と物語の介入」、シミュレーションゲームなら「戦略性」だそうです<ref>『ゲームプランとデザインの教科書』、P152</ref>。
ただし上述の書籍によると、1990年代は今よりもゲーム性とシステムが重視されていたとの説明があるので、裏を返せば2010年以降の現代では、ゲーム業界ではゲーム性の重視の比率は1990年代よりも減っているかもしれません<ref>『ゲームプランとデザインの教科書』、P302</ref>。
『ゲームプランナー入門』(吉冨賢介 著)では、ゲーム性とは「課題や挑戦の仕組み」であると結論づけています<ref>吉冨賢介『ゲームプランナー入門』、P36</ref>。そして、この達成感こそが「ゲームならではの面白さ」だと述べています。
;アクションパズルゲーム「I.Q」
メディアクリエイターの佐藤 雅彦氏(「だんご3兄弟」や「ピタゴラスイッチ」等を手掛けている)が、初めてかかわるコンピュータゲームで、ソニー・コンピュータ・エンターテインメントとの共同企画で、のちに「I.Q」(1997年にシリーズ第一弾を発売)と呼ばれるシリーズに携わった時、プロトタイプが全くゲーム性のないものになってしまい、それをプレイしたソニーの幹部陣の顔色が非常に曇ってしまったようです<ref name="br67">川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P.67</ref>。
ここでの悪い反応、薄い反応の理由がわからなかった佐藤氏が、階段の踊り場でソニーの新人に尋ねてみると、「それが、あの、ゲーム性がないっていうか・・・」と言われたと出典の対談集に書かれています<ref name="br67" />。
基本的に佐藤氏は、プロトタイプの企画を提案しただけですが、ソニーにはプロトタイプを作るための部署があるらしく、1~2ヶ月かけてそこでプロトタイプが作られたようです。
この問題の責任が誰にあるかは、大した重要な事ではありませんが、商業作品としてプロトタイプを作る以上は、どこかの段階でゲーム性を意識して、プログラムに盛り込む工夫が必要になるでしょう。
===ゲームの見た目とは?===
ふつうゲームのプレイヤーは、まず最初にそのゲームの「見た目」を判断し感受するでしょう。ですからその見た目のインパクト、興味を呼び起こす構成が必要になります。
例えばスーパーファミコンRPG『新桃太郎伝説』では、開発当初はドラゴンクエスト5 のようなマップ画面のトップビューUIでしたが、開発中にクォータービューの他社製RPGが発売されて高い評価を得たので、マップUIを(トップビューではなく)クォータービューに作り直したようです。このことは攻略本『新桃太郎伝説 究極本』に開発裏話として書かれています。
一方現在でもこの方向の試みは重要なようで、書籍『ゲームデザイン プロフェッショナル』の著者は、他企業の製品の画面と、自社の製品を目で見比べる分析方法で、自分たちの製品のUI の問題を見出しています<ref name="gdp199">『ゲームデザイン プロフェッショナル』、P199</ref>。
割と素朴で単純で即物的な見た目、「かっこいい」とか、「ぱっと見派手」等の要素が非常に重要なようです<ref name="gdp199" />。
商業としてゲームを作る以上は、ペイしなければ企業も事業の継続も維持できませんから、考慮せざるを得ない問題ではあります。
== ゲーム開発ツールを使う場合 ==
====開発ツールのライセンス条件====
ゲーム開発ツールのなかには、そのツールで開発したゲームソフトに義務として「この開発ツールで開発したソフトウェアは、ソースコードを必ず公開しなければならない」などの条件をつけている場合があり、このような条件を「開示義務」(かいじ ぎむ)または「ソース開示義務」などといいます。
ソース開示が嫌な場合は、開示義務のあるツールは使わないのが正解ですね。
ゲームに限らず、ソース開示を義務としている開発ツールは多くあるので、ライセンスには気を配る必要があります。
「有料ソフトの販売を禁止」とか「アダルト作品の開発は禁止」などの条件をつけている場合も、ありえます。
ですからゲーム開発において、ツールのライセンス条件の確認は、非常に重要です。
{{コラム|GPLライセンス違反|
GPL(ジーピーエル)というライセンスがあって、Linuxなどのオープンソースで使われています。このGPLを組み込んだプログラムは、ソースを公開しなければいけません。
ですから、ソース公開したくないプログラムには、GPLソフトウェアは組み込めません。
ゲーム業界でも、GPLライセンスのソフトウェアを組み込んでしまったために、呼出し元ソフトウェアでのソースコードの一部を公開することになったゲームがあります。2005年頃、『ToHeart2』という美少女ゲームが、xvidというGPLソフトを取り込んだ疑惑によって、GPL違反の疑いでソース公開になりました。([[w:ToHeart2#GPL違反とソース公開]])
GPLでも、たとえばLinuxサーバ上でソース非公開のアプリを動かすように、GPLのソフトウェアを非公開ソフトとは独立した状態で使う場合は、ソース公開の必要はない、と、考えられています。(これが必要有りとなると、オンラインのプログラムやネットゲームは全てソース公開しなければならなくなり、非合理な結果になる。)
特定のプログラム自体に、GPLソフトウェアのコードを取り込んだ時、ソースコード公開が必要になります。
}}
{{コラム|BSDライセンス他|
オープンソースの中には、どのような利用法であっても、利用者にソース公開を求めないライセンスもあります。BSDライセンスとMITライセンスはソース非公開で利用できます。
ゲーム制作ツールの吉里吉里Zは、修正BSDライセンスで公開されています。
もしライセンスのことがよくわからない、またはライセンスの学習に時間をかけたくないなら、オープンソースのツールを使うなら、BSDライセンスを使うのが安全です。
}}
[[w:DXライブラリ]]は、GPLでもBSDライセンスでもありません(DXライブラリ説明書「DxLib.txt」には、どこにも「GPL」とも「BSD」とも書いていない)。DXライブラリは単にソースコードが公開されていて、著作権者の「山田 巧」氏が著作権を保持しているオープンソースなライブラリです。
このように、ネット上でソース公開されているソフトウェアには、ライセンスの複雑な解釈を嫌ってか、「BSD」や「MIT」などのライセンス条件を名乗らないオープンソースソフトウェアもあります。
{{コラム|自作ソフトでソース開示|
昨今ではオープンソースやフリーソフトウエアの発展などの背景もあり、「自作ゲームのソースコードやソースファイルも開示しよう」と思うゲーム作者もいるかもしれません。
然しソースコードを開示していることが原因で、トラブルに巻き込まれる場合もあるかもしれません。自分の作ったゲームのコードが悪用され、トリッキーないたずらや嫌がらせ、誹謗中傷などを受ける可能性も全くないわけではありません。
そこでライセンスに、利用による損害に対する保証が無いことを明示するのは、ある程度有効でしょう。大抵の著名なフリーソフトウェアライセンスには、この条項があります。他者の悪意を完全に防ぎ失くすることは難しいのですが、ある程度の対策は見出されていますし、自身でも見出していく必要があるでしょう。
}}
====開発ツールを使用しないという事====
下記の理由(機能制限および移植性の悪さ)の問題から、あまり大規模な作品は開発ツールでは作らないでおくのが安全です。
大規模な作品の場合、Visual C++ などでコードを書いて開発することを推奨します。
=====機能制限=====
ゲーム開発ツールを使う場合、そのツールにもよりますが、「○○ができない」、つまり特定の目的を果たすための機能を持っていない場合があります。
Visual Basic や Visual C++ には普通にある関数でも、開発ツールには無い場合も多い。
また、もし、いったんはゲーム開発ツールを使って目的の機能を持ったシステムを作ったとして、さらなる機能をそのシステムに追加しようとするときに、大幅な作り直しが必要になる場合があります(拡張性の悪さ)。
システムがモジュール化されていても、そのモジュール部分では大きく改変する必要がある場合もあるでしょう。
ですからゲーム開発ツールによるゲーム制作では、あまり大作を作ろうとしないほうが安全です。開発ツールで作る作品は、比較的に小規模な作品に、とどめておくことを推奨します。
Windowsの場合、本来なら Visual C++ などを使って、プログラム文法のいろいろな事に留意しながらプログラムを書きますよね。開発ツールを使う場合、 Visual C++ のコードを書かずに、ほぼマウス操作だけでプログラムを作ろうとしているわけですから、何かしらの制限があります。拡張性の悪さは、プログラム文法などの学習の負担を減らすためのトレード・オフのようなものですね。
=====移植性の悪さ=====
また、もうひとつの問題点として、C言語への移植性の悪さがあります。
ソースコードが公開されていない開発ツールの場合、異なる開発環境にゲームのソースファイルを移植するのは、ほぼ不可能です(仮に、開発ツールのランタイムを模倣できたとしても、著作権などの法的な懸念が生じる可能性あり)。
ゲーム開発ツールで作ったソースを、Visual C++のソースに置き換えるのは、簡単にはできないし、ほぼ全面的に新たに書くことになるでしょう。
==イラストレーター、デザイナー==
ゲーム制作、業界において、イラストや音楽を作る部署、人物は、まとめて、"アーティスト"と呼んでいるようです。
ゲーム界の場合デザイナーというのは、プランナーやディレクターのことであり、管理職的な設計者のことで、美術的なクリエイターではない。design という英語には、機械建築の設計という意味もあります。
映像関係、画像系のアーティストはグラフィッカーと呼ばれることもあります。ムービー担当者、特にゲーム界では3D-CGの制作者をアニメーターと呼ぶことが多いようです。アニメーション業界では主に、手描きの原画、動画マンをアニメーターと呼びますが、最近は3D-CGアニメーション映画も多いので、すこし状況が変わっているかもしれません。
ゲーム業界とアニメーション業界、各会社企業、過去と現在で、「原画」「仕上げ」「絵コンテ」等、一般的な作業に関する言葉が、それぞれの状況で微妙に違った意味で使われることも多いですね。
…ところで前編集者はわざわざこの項目を作ったうえで、色々な場所での言葉の意味の違いを、クドクドと自分勝手な分かりづらい説明で長々述べた後、「混同しないように気をつけましょう。」なんて馬鹿馬鹿しい言葉で締めているんだけど、この人物の意図はどこにあるのだろう?
例えばデザイナーというのは一般的に、造形作品、図案、意匠を考案する人のことを言うのだから、ゲーム界の外の人間が多少その業界内での意味を取り違えても、それほど致命的なミスでもないし、罵倒、愚弄されるいわれもなければ、好き放題にその相手を罵倒、愚弄していいわけでもない。間違えて使っている人を見たら、その都度やんわりと教えてあげればいいだけじゃあない? だいたいその世界に現実に身を置いたら、そこでの言葉の意味、使い方なんて自然に覚えるものだし…。
それを得意げにこれが違うあれが間違いといちいち理屈書いて、いい気になって威張っているこの人物は何者なのだろう?
現編集者が思うには、この人物は、学問、知識、知恵、科学とは何かという事を、根源的に取り違えている、のだろう。
==操作性==
操作性について、親指と人差し指<!-- ←ここ,中指って書いてあったけど,こっちだよね? -->だけでボタンプッシュなどの操作ができるように作成するのが基本です。中指、小指、薬指はコントローラのホールドに使うぐらいです。人間工学的に、小指や薬指は力が弱いので、微妙な操作には向かないことが知られています<ref>川上大典ほか『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.48</ref>。
一般的にゲームプログラミングでは、
# プレイヤーからの入力を扱うことができる。
# ゲームが提示する内容を表示することができる。
入力と出力、この2点が機能として必要になります。
プログラミング言語とプレイヤーからの入力については歴史的にも、あまり変化がありません。言語では主に[[C言語]]、[[C++]]が用いられる。[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
パソコンゲームでは、プレイヤーからの入力には通常、キーボードかマウスを利用します。他に[[w:ジョイスティック|ジョイスティック]]や[[w:ゲームパッド|ゲームパッド]]が利用される場合もあります。家庭用ゲーム機では[[w:コントローラ|コントローラ]]が利用されることが多いのですが、[[w:ニンテンドーDS|ニンテンドーDS]]や[[w:Wii U|Wii U]]では[[w:タッチパネル|タッチパネル]]、[[w:Wii|Wii]]では複数の入力機器が提供されることが発表されています。各種入力機器をプログラムから扱う手法自体は、普遍性があり、入力機器ごとに大きく変化しない、と、考えられています。[[w:デバイスドライバ|デバイスドライバ]]、[[高等学校情報B]]には、プログラムから周辺機器を扱う方法について多少の記述があります。
画面表示のうち、3Dの表現は割合難しく、ある程度の数学(高校、あるいは場合によってはそれ以上)の理解が必要でしょう。2Dに関してはプログラムの面では、さほど難しい部分はありません。
==処理速度の問題==
基本的にプログラミングでは、関数を使って、処理をコンパクトにまとめ、定数ではなく変数で柔軟性のある操作をすることが求められますが、ゲームの場合は、この構造のせいで処理速度が低下することがあります。
現在のCPUの性能、速さはかなり高くなってはいますが、プログラム処理は無限に煩雑化できますから、やはり高度な処理を短時間でなすことが求められます。特にゲームは、リアルタイムの反応のタイミングが非常に重要ですからね。数学の指数計算についての雑学で、「新聞紙を42回おりたたむと、月に届く距離になる」というものがあります。(新聞紙の厚さ)*2^42、ですね。もっとも新聞紙の物性から言って、ほぼ不可能な操作ですけど^^;;。コードの内容、組み合わせによっては、このように計算量が指数関数的に膨大になってしまい、処理速度が非常に遅くなってしまう場合があります。
ですが、このセクションで後述するように、関数を用いる場合の解決策(※概要:あとでdefineやinlineに置き換え)があるので、プログラミングの初期のほうは、とりあえずバグを未然防止するために関数を活用するべきでしょう。
1980年代頃のファミコンなど古い時代のゲームでは、ストレージ容量(ハードディスク容量のこと)が、ボトルネックでした。「容量不足でイベントをいくつか削りました」と、当時のRPGなどのゲーム作家が述べるのは、ストレージ容量の不足のことですね。ただ当時のファミコンはROMカセットでハードディスクは無いので、まさにストレージ容量という言葉が適切でしょう。
しかし2010年以降の現代では、ボトルネックになっている要因は、ストレージ容量不足よりも処理速度です。
ゲームプログラミングに要求されるコード特性は、科学計算ソフトウェアや金融プログラミングなどの手法とは異なります。情報工学・情報科学で適切とされる「構造化プログラミング」などの歴史的に発展してきたプログラミング・パラダイムの理念とは反するようなコード開発方針になる場合もあります。しかしゲームプログラミングに限らず、限定されたハードウェアで特定の結果を速く得るためには、様々なトリッキーな手管が必要になるでしょう。
;ツクール等制作ツール
RPGツクールの制作元のカドカワ(アスキー社→エンターブレイン社→カドカワ(かつての「角川書店」) )では、PRGツクールでのアクションゲーム開発は推奨していません。アクションゲームの場合は、同じカドカワの「アクションゲームツクール」で制作するよう、薦めています。
アクションゲームとターン制RPG では要求される特性が大きく異なり、なかには、ほぼ対立しているような性質もあります。
ツクールやウディタでも、万能にあらゆることがスタマイズできるわけではなく、その制作ツールの特性に依存しますし、主に処理速度の低下しない部分についてユーザが創作できるようになっているでしょう。
多くのRPG制作ツールはマップ操作や戦闘画面の基本システムのルーチンそのものは、あまりカスタマイズできません。画像や音楽は挿入できますが、例えば戦闘プログラムなら、「コマンド」の命令文など一部の派生的な部分だけが独自に作れる程度でしょう。
ですから、ツクールでどうしてもアクションRPGを作りたい場合、基本システムの改造はかなり困難だろうし、別途、アクションRPGのような動作をするマップイベントを作成する・・・ぐらいでしょうね。
ツクールやウディタでターン制RPG以外のジャンルを制作するのには、実質的には限界があり、さまざまな制約が生じます。
;具体的な手法
初期段階では関数や変数を活用してプログラミングし、処理速度を高める必要がある箇所にだけdefineマクロ等を用い別の方法に置き換える。C++ならinline関数という前処理命令もあります。
通常の関数で記述していったソースコードを、あとから一括変換などでdefineマクロやinline関数などに置き換えることは比較的に容易です。
また、関数を経由しているので、マクロを使った場合でも比較的にバグが混入しづらくなっているかもしれません。(defineなどの前処理命令マクロは、用いるとバグを発見しづらいので、なるべくマクロの利用を避けるべきなのが、ゲームプログラミングに限らないプログラミングの定石です。)
一方、まったく関数を使ってないコードを、あとからdefineマクロなどに手作業で置き換えるのは、なかなか面倒です。
最終的には一括変換で置き換えることが出来ますから、途中の段階では、処理速度を気にせず関数を使うのがいいでしょう。
なお、defineマクロは、値の置換以外には用いないのが、プログラミングの定石です。このため、たとえば黒色RGB値の<code>10,10,10</code>といった配列にdefineマクロを使うべきかどうか悩みますが、とりあえずなるべく値周辺にだけdefineマクロを適用するようにするようにするのが良いでしょう。いっぽう、一般の命令文をdefineマクロで置き換えるのは、避けるべきでしょう。
たとえば、処理に0.5秒ほどの時間の掛かってもかまわないような場所は、どんどん、関数に置き換えていっても良いかもしれません。
アクション性のないゲームなら、関数をぞんぶんに活用できます。
ターン制RPGやシミュレーションゲーム、アドベンチャーゲームなど、関数を活用しやすいでしょう。
一方、アクションゲームなどでキャラクター操作中のコードのように頻繁に使って、しかもそのゲームの中心的なコードなら、そこは最終的には関数にしないほうが良いかもしれません。
このように、ゲームのジャンルによって処理速度に対する必要な水準が異なりますので、プログラミング時における関数などの利用の方針も異なります。
以上のように、何でも関数にすることは避けるべきです。関数は処理速度の問題がありますので、必要性のある部分だけ関数にするべき。関数を使わなくても、for文やif文などのブロックの構成を適切に組み合わせることで、コード中のmain関数以降の部分でコード共通化できることは色々とあります。
「共通性のあるコードだから」といって、大して長いわけでもないコードを関数に置き換える事は、速度維持には寄与せず、ゲーム制作のプログラミングとしては、悪手となるでしょう。
===2Dの画面出力===
画面出力の場合も入力機器の場合と同じで、これらを操作する方法はOSごとに異なっています。先ほどあげた GTK+, Qt, SDLなどのライブラリはクロスプラットフォームの画面出力を提供しているため、これらを利用することで全てのプラットフォームで動くプログラムを作ることができます。<!--画面出力を扱うためには近年の[[w:ビデオカード|ビデオカード]]の発展についても見る必要があります。しかし、ビデオカードの機能は2次元の描画に関してはあまりあらわには見えないので、この話題は3次元の描画を行うときに再び戻ってきます。-->
*[[ゲームプログラミング/ブロック崩し]]
*[[ゲームプログラミング/画面出力]]
==目次==
=== ジャンル別のプログラミング手法 ===
==== 3Dグラフィック ====
* [[ゲームプログラミング/3Dグラフィック]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
==== RPG ====
* [[ゲームプログラミング/RPG]]
==== アクション ====
※未作成
==== パズル ====
※未作成
==== シミュレーション ====
※未作成
=== ゲームのデバッグ ===
* [[ゲームプログラミング/デバッグ]]
=== 入力 ===
OSの種類によって、キーボード入力やマウス入力の受け付けのさいのプログラムの書き方は違う。
Windows API での具体的な手順は『[[ゲームプログラミング/入力]]』で説明する。
=== ゲームエンジン ※未完成 ===
* [[ゲームプログラミング/Unity]] ※リンク先ページの編集者が現状ではUnityの著作・調査を放棄中なので、調べ物としては役立ちません(2021年12月19日に本文を記述)。
=== 非プログラミングのゲーム製作の関連作業 ===
==== バランス調整 ====
*[[ゲームプログラミング/バランス調整]]
厳密にはプログラミングの話題ではないが、ゲーム製作では必要な知識なので、サブページで説明する。
:※ゲームデザインに関する記述をここに集積し分離したい、という編集者の意図もある。
==== ゲーム用の書類の書き方 ====
説明書や仕様書(しようしょ)の書き方については、『[[ゲームプログラミング/書類]]』で解説する。
== 未分類 ==
===Visual C++プログラムによる文字画像の出力===
Visual Studio付属のフォームデザイナ(VSの用意するGUI自動作成ソフト)によるGUIオブジェクト作成では、RPG用には使いづらい。いや、ひょっとしたら上手に使う方法はあるのかもしれないが、様々な理由で難易度は高い。
そこでまず、Visual C++で、フォームデザイナをなるべく使わずに文字や映像を出力する方法を考える。
選択肢は、幾つかある。
1.フォームデザイナを1つも使わない方式
*Windows APIで入力していく方法。(Wikibooksに『[[Windows API]]』の入門書があります。)
*DirectXで入力していく方法。DirectX自体はWindowsAPIを利用している。
2.1つだけフォームデザイナのパネルを使う方式
*フォームデザイナで「パネル」という画像表示機能のコンポーネントを一つ用意して、そのパネルで表示する画像をゲーム内のストーリーなどに応じて切り替えるだけで、すべての画像表示を行う。
フリーソフトでゲーム用ライブラリの『HSP』はWindows API を呼び出す仕組みになっています(HSP関連のサイトを見ると、Win APIプログラミングの解説をしている場合もある)。
フリーソフトでゲーム用ライブラリの『DXライブラリ』は Direct X を呼び出す仕組みになっています。そして、ゲーム開発ツールのひとつであるウディタのソースコードは、DXライブラリとVisual C++ を使って書かれていると、作者が公表しています(ただしソースコードは非公開)。しかし、ウディタを用いたRPGプログラミングでは DXライブラリによるコーディングはしない。ウディタにはコード入力の機能は無く、マウス操作や、キーボード操作、キャラ名称や会話文などのテキスト文字や数値の入力のみに対応している。
===乱数===
そもそも乱数とは何かという問題があるが、それは高度な数学的な議論になるだろうから、我々はその問題には深入りできない。
ゲームにおける乱数的な処理では、事実上ランダムな値にならず、演出や調整のためにアルゴリズムが介入している場合も多い。例えばゲーム中のくじで「外れ」続くと、当たり確率が変動し、次からは当たりやすくなるアルゴリズムなども良く使われる。<ref>『ゲームプランナー集中講座』、P232</ref>。
ゲームは娯楽であり、実用目的のシミュレータではないし、アルゴリズム介入で、確率的にもいんちきが多いので、あまり厳密なランダム性が問題になることは少ないだろう<ref>『ゲームプランナー集中講座』、P231</ref>。
例えばさいころというのは典型的な乱数器だし、ゲームにもよく使う物だろう。
無印C言語には標準的乱数関数 rand()があるが、これを乱数発生に使うことに批判的な意見もあるし、機能もやや不足していると見れる。
Windows64bit では int rand(void) の出力は 32bit 整数だろう。まず stand関数で初期化してから rand()を呼ぶごとに疑似乱数が帰ってくる。これの複数回の連なりが乱数列だね。帰ってくる値は0 以上 定数RAND_MAX の値以下。
例えばさいころの数値が欲しいなら、rand の返り値を6で割った後、余りに1足せば、とりあえずそれらしいものはできる。
RAND_MAXは rand()の属性として定数が与えられているだけだから(Windowsで0x7FFF)、この値の変更はできない。
まあこれでもそこそこいい加減な乱数として機能するだろうが、最近ではもう少し改良された、質の高い乱数関数もある。
また、改良された乱数関数は、乱数の範囲も指定できるから何かと使い勝手が良いし、バグを防ぐ効果もあるのだろう。
<syntaxhighlight lang="cpp">
Random^ saikoro1=gcnew Random();// Random^ でRandomクラスの変数を作っている。gcnewはインスタンスをつくるための演算子。
int detame; detame=saikoro1->Next(1, 7);// Next メソッドで「〇〇以上△△未満」の乱数を指定できる。「->」はメンバーアクセス演算子。
MessageBox::Show("目"+detame.ToString()+"が出ました。");
</syntaxhighlight>
↑例えば上述のコードは前編集者が示したものだが、これは .NETプログラミングですね。.NET のSystem::Randomクラスを使っている。.NETのクラスは普通、C#かVisual Basic で利用するので、Visual C++で使えるようにするには結構面倒な手管がいるが、その辺は読者諸兄、ヘルプやネット情報を参照して、適宜辿り付いてほしい。
C++ の場合はむしろ、 #include <random> を宣言してそこで使える関数を使用するほうが簡単でしょうね。この場合でも、乱数としての精度も高いし、帰り値の範囲指定もできる。
===画像のちらつき===
画像がひんぱんに変化するアプリでは、画面が、ちらつく事がある。画面のちらつきは、ゲームのように、画像を凝視するアプリでは、かなり利便性を損なう。
キャラクターが1歩移動するだけで、画面全体がちらついたりする場合もあり、かなり、プレイヤーの不満になる。
これは、ダブルバッファ(「裏画面」と、良く言われる)という技術で、解決を図る。
Direct Xの用語では「スワップ チェーン」と呼んでいる。
.NET Framework開発環境の C++や C#でもダブルバッファの機能があると解説されている。いくつかのGUIオブジェクトのプロパティで、ダブルバッファの設定項目がある。
しかし前編集者が実験したところ、この機能を有効に使って確認することはできなかったとの指摘がある。ひょっとしたら何らかのマイクロソフトの解説に間違いがあって、工夫次第では利用できるかもしれないが、少なくとも今現在のこのページでは、その問題に関するリファレンスは提供できない。
そこでやはり、以前の項目と同様、Win32 API または DirextX の利用をこのページでは考えたい。
前編集者は、.NET Framework のフォームデザイナでは、ちらつき自体は解決できそうだが、グローバル変数の共有が困難だったり、アプリ内から終了コマンドが使えない、などの難点があると指摘している。
ただ現編集者はこの2点に関しては、解決策はあると思うが、しかし特に調査はしない。
前編集者は、.NETプログラムでゲームを作る難点をいくつも上げているが、おそらくどれも、.NET の仕様や全貌に精通すれば解決できるように思えるが、そもそもその全貌がかなり広大なので、解決の道のりは長いだろう。
そこで少なくともこのページでのWindowsゲームプログラミングは、Win32 API を利用したものになるだろう。
==セーブ、ロード、データベース==
===セーブ機能とロード機能の作り方===
ゲームでもシリアライズ機能が必要なことは多いだろう。数値(HPなどの各種パラメータ現在値)や文字列(例えば、プレイヤーの作成したキャラクターの名前)や現在地やフラグ状況などなど、セーブの機能は欲しい。一番簡単な方法は、C言語の fopen 関数のテキストファイル書き込み機能で、テキストファイルとしてセーブすることだろう。
Windows API には CreateFile関数 があるが、テキストファイルでの素朴なセーブは一番簡単で単純なセーブ法だろう。そしてテキストファイルを読み込んでプログラムに各種変数を配置して、ロードとする。
書き込みとしては、一番単純なC言語記法では、fprintf ですかね。C++としての書き込みをしてもいいし、読み込むのも、一番基本的な方法で。基本Cだとしたら fscanf で、この関数でテキストの数値も変数として読み込めるはずですよ。場合によっては atoi関数 で文字列→数値の変換をすることもありますかね。
基本的にデータファイルは、OS もアプリケーションも、テキストファイルとバイナリファイルの2分類で考えるでしょう。でもテキストファイルだってバイナリの集まりなんですが、テキストを扱うファイルだけ特別視していると考えていい。
そして多少それらしいデータを作りたいときは、バイナリファイルで作るという事になるでしょう。
バイナリファイルでもデータとしてのファイルと、OS が機械語または何らかの仮想的な機械語として扱う実行ファイルがある。それらのバイナリは種類に応じて多くは冒頭にファイル識別子の情報があるだろうし、OS や アプリケーション側で工夫を凝らして、特定の条件を満たす場合しか動作しないようにしているだろう。そしてバイナリファイルを扱うときは、セキュリティの安全性も考慮するだろう。
基本的にプログラム側は何でもありだが、識別子の判別その他、ある程度様々な考慮をしないと、困った事態が起こり、プログラマーが責任を問われることも起こるかもしれない。
まあその時はいつものように口先だけで謝り、それでも許してくれなかったら、腹をかっ割いて死んでお詫びすれば、世間の人たちは美事な武士道精神と言って、口々に褒め称えてくれるだろう^^。←もちろんこれは冗談^^;;;。
市販のパソコン用ゲームや同人ゲームでは、テキストファイルではなくバイナリでデータ保存するゲームの方が圧倒的に多いだろう。その方がそれらしいしかっこがつく。ゲーム開発ツール側自体も、そうなっている場合が多い。RPGツクールもウディタも、セーブデータの形式はバイナリ。
テキストデータは基本エディタで開けるが、バイナリデータも内容によっては結構ぐちゃぐちゃの状態で開ける。バイナリデータはバイナリエディタで開ける。バイナリエディタのリードオンリーモードやバイナリビューアみたいなものがあれば、データーを壊さないで結構安全にデータ調査できる。
データ内容を秘匿したければ、バイナリ化だけではなく、暗号化も必要になるかもしれない。
=== その後のセーブ・ロード機能の整備 ===
セーブ&ロード機能の作成のプログラミングに挑むなら、セーブから作るほうが作りやすいだろう。
しかし、最終的にセーブ用関数とロード用関数の一部を統合する場合などは、ロード機能を基準に考えたほうが良いだろう。
この理由は、まず、セーブ機能とロード機能では当然、セーブファイルの読み方の書式を統一しなければならない。(でないと、ロードの前後で、ゲーム主人公の能力値や進行状況などが変わってしまい、セーブとしての機能を果たさない。)
なので、ともかくセーブとロードにおけるセーブファイルの書式を統一する必要がある。
ロードのほうが処理が複雑であり、プログラムが複雑になるので、ロード機能を作りやすい書式なら、セーブ機能も作りやすい。つまり、ロードの都合だけしか考えていない書式であっても、比較的ラクにセーブ機能のプログラムを書ける。
一方、セーブ用を基準にして考えたセーブファイル書式は、必ずしも、ロード機能のプログラムを作成しやすいとは限らない。
では、なぜロード機能のプログラムは、複雑になりやすいのか?
まず、セーブの場合、最終的に外部に出力されたデータには、データ型の差異(int型やchar型などの差異)は無く、すべてテキスト文字列として処理されているので、プログラムは比較的に単純である。
しかしロードのほうは、読み取った文字列がint型なのかそれともchar型なのかなどの解釈をプロプラムで指示しなければならないので、よってロードのプログラムはやや複雑になる。こうして、セーブ機能よりもロード機能のほうがプログラムが複雑になりやすいのである。
== ゲーム中の特殊イベント ==
* [[ゲームプログラミング/特殊イベント]]
たとえばRPGなどでは、ゲーム中で1回しかおきない特殊なイベントとかを作りたい場合があるでしょう。RPG以外でも、シミュレーションゲームなどで特殊イベントを実装したいこともあります。たとえば、もし日本の中世の戦国時代シミュレーションゲームで「桶狭間の戦い」が3回も起きたりしたら困ります。
そういう話題について、とりあえずの叩き台的な、「こうプログラミングしたら、いいんじゃない?」的なことをリンク先では説明しています。
== スケジュール管理の教養 ==
[[File:Tokai Hairo.jpg|thumb|500px|ガントチャートの例:東海発電所の廃止解体工程]]
個人でのゲーム開発には全くの不要な知識ですが、スケジュール管理表といわれる技法がいくつかあります。
「作業責任分担表」(TRM: Task Responcibility Matrix)といわれるスケジュール表から、
それをグラフ的に図示したガントチャートといわれる表を作って、その表を見て作業計画を判断する方法です
<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
{| class="wikitable" style="float:left"
| 仕事
| 担当
| 状態
| 開始
| 終了予定
| 終了日
|-
| 仕事1
| 田中
| 済
| 2021/10/03
| 2021/10/10
| 2021/10/10
|-
| 仕事2
| 田中
| 仕掛
| 2021/10/11
| 2021/10/13
|
|-
| 仕事3
| 鈴木
| 済
| 2021/10/05
| 2021/10/08
| 2021/10/08
|-
| 仕事4
| 山田
| 未着手
| 2021/10/13
| 2021/10/17
|
|-
|}
{{-}}
ガントチャートでは普通、横軸に日程をとります。
ゲーム業界でもガントチャートの横軸は日程です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
ガントチャートとして図示することで、どこがボトルネックなどのリスク要因になりやすいのかが、一目瞭然です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
なので、それを見越して、スケジュール管理をします。
このTRMとガントチャートは、IT業界だけでなく建築工事でも使われるので、
社会人の知識のひとつとして知っておくと良いです。
ガントチャートによるボトルネックの洗い出しも、建築学の教科書でも良く教わる内容です。
よく住宅リフォーム工事などで、一般人でも建築業者の提示するガントチャートを見る機会があります。
新人の段階でそんなの書く機会はないかもしれませんが、しかし知っておくと上司からの命令が理解しやすいので、
知っておくと得でしょう。
== ストーリー作成などの順序 ==
ストーリー作りに限らず、ゲーム作りではゲーム全体を先に作るのが先決です。ニュアンスは違いますがアトラス社いわく(ゲーム開発では)、おおむね「ゲーム全体に全体に血を回すのが先」といった内容の格言があります<ref>[https://news.denfaminicogamer.jp/projectbook/191030a/2 『【ゲームの企画書】『ペルソナ3』を築き上げたのは反骨心とリスペクトだった。赤い企画書のもとに集った“愚連隊”がシリーズを生まれ変わらせるまで【橋野桂インタビュー】』2019年10月30日 11:30] 2020年12月1日に閲覧して確認.</ref>。
プレイヤーが見たいのは、ゲーム全体のストーリーやテンポといったゲームの全体像です。細部は、あくまで補助的であり、そういった細部に対するプレイヤーの興味も、あくまでオマケの範囲でしかないのです。
さて、暗黙の前提として、ゲームのストーリーは、システムと連携・調和したものでなければなりません。
このため、ゲーム作家によっては、先にシステムを決めてから、あとからストーリーを作るような方法論を採用しているクリエイターもいます<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.306</ref>。
さて、ともかくゲームのストーリー作成は、なんらかの方法で、全体像を先にきめてから、あとから細部を作っていきます。
これを実現するための方法として、いくつかの方法があります。
ドラマの脚本などで使われる、「ハコ書き」という方法を使う人もいます。全体像に当たる「大ハコ」を記述してから、「大ハコ」→「中ハコ」→「小ハコ」と記述していく方法です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.184</ref>。
そのほか、別の方法としては
:* エンディングを大まかに先に作る
:* 機能の実験を簡易でいいので事前にしておく(※プロトタイプの項目を参照)
:* 使用頻度の高い部分から作る
のような方法もあるでしょう。
そのほか、書籍『ゲームプランナー入門』で紹介されている事例だと、アルファ版(α版)を中盤から作り始めています<ref>吉冨賢介『ゲームプランナー入門』、P17</ref>。α版の製作目的の一つとして、そのゲームが本当に面白いかの検証や(駄目すぎたら製作中止)、改善するとしたらどこかの洗い出しが目的ですが、中盤だとそのゲームの全体像がわかりやすいので検証しやすいからのようです。
作品やジャンルや製作目的などによって、エンディングからか中盤からか、どこから作り始めるかは若干の違いはあるでしょうが、ともかく必ずしも冒頭部から作り始める必要がないということです。
;エンディングおよびラスボス戦闘を早めに作る場合
まず、ゲーム用のストーリー(ゲームシナリオ)の作り方ですが、学校などでの作文の書き方の順序と、ゲームシナリオの書き方の順序は、違います。
作家にもよりますが、ゲームシナリオを作る場合、エンディングを早い時期に作る人もいます<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
文献『ゲームプランとデザインの教科書』によると、シナリオでなくシステム面についても、先にゲーム全体のクリア条件を決めてから、あとから各ステージなどのクリア条件を決めていくことが多いようです<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.253</ref>。
では、シナリオの仮のエンディングについて考えていきましょう。このエンディングは、当面の仮のエンディングなので、あまり作りこむ必要がありませんが、しかしエンディングが必要です。
エンディングのシナリオと、キャラクターの性格づけの設定があることにより、そのゲームで何を主人公に目指させるべきなのかが、作者にハッキリとします<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
ともかく、方法は作家ごとに色々と違いはありますが、そのゲームの全体像を何らかの方法で決めるのが先です。
また、ゲームでは最後のラスボス戦がそのゲーム中でもっとも高負荷だったり、全部のシステムが組み合わさってたりしますので、先にエンディングを作っておくことで、そのゲームで最大負荷の状態を検証する事が出来ます<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
また、3Dゲームでは、RPGなら戦闘シーン、アクションゲームならアクションシーンが、一般的に、最も高負荷です<ref>ntny著『ローポリスーパーテクニック』、ソフトバンククリエイティブ、2010年2月16日 初版 第5刷、P28</ref>。
処理オチの確認とかも、この方法で確認できます。
また、ラスボス戦およびエンディングは、そのゲームの大きな見所のひとつであり、ほぼ最大の見所がラスボス戦およびその前後です。
いっぽう、中盤などは、比較的に重要性が下がります。
なので、スケジュール遅延や容量不足などで、ストーリーを短くしないといけなくなった時などは、ラスボス戦以外の場所を削ることになります<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
よって、ラスボス戦などは削る可能性が少ないので、先にラスボス戦を作っておけば、たとえスケジュール遅延などをしても、先に見所を作ってあるので、早くリリースしやすくなります。
{{コラム|イラストなど異分野での類似事例|
似たような、先に結末を決める事例は、イラスト技法にも存在します。
1995年ごろ、イラスト雑誌『コミッカーズ』(1995年 コミッカーズ季刊 夏号)に、当時の人気漫画家&イラストレーターの藤島康介がインタビューされたのですが(なお、その号の表紙は別の漫画家(唯 登詩樹))、
藤島はインタビューにて、おおむね内容『よく若い漫画家さんから相談で「先生みたいに女性の長い髪を書くとき、毛先を書くのが難しいです。根元は書けるのに」との相談を受けるのですが、
僕(藤島)は髪を描くときは毛先から始めて根元に向かって描いてます』みたいなインタビュー返事をしました。
こういうふうに、大切なのは頭の使いようです。要するに、ズレるのが怖い場所は、先に位置決めをすればいいのです。髪の房(フサ)の根元と毛先だったら、ごく一部の場所を除いて、読者の目線では毛先のほうが目立ちます。
だったら、作画の際の誤差は、読者には気づかれない根元の部分に押し付ければいいのです。
よくよく考えれば、イラストに限らず機械製図とかでも普通にそういう位置決めの優先指示の記法はあるのですが、
しかし世間の人は、なかなかそういう発想を異分野に応用できません。普通の人はついつい、実際の髪の伸びる順序どおりに根元から描いてしまいます。
}}
* 目標の提示
ゲーム中の目標の明確化は、シナリオの設計手法としてだけではなく、たとえば各ステージ目標の提示などは、プレイヤーをゲームに引きこむ手法にもなります。
というか、文献『ゲームプランナー入門』によると、もしゲームの目標や課題が満足に語られていないと、プレイヤーは最悪、「?」となり、コントローラーを置いてゲームを中断してしまいます。なので、設計の際、各ステージやエリアなどの冒頭で、そのステージの課題や目標などを明示する必要があります<ref>『ゲームプランナー入門』、P39</ref>。
ファミコンの古いアクションゲームだとゲーム本編では目標は語られていませんが、しかし説明書などではキチンと目標が語られており、実際にスーパーマリオブラザーズの第1作目では説明書では目標がクッパを倒してピーチ姫を救出することだと語られています<ref>『ゲームプランナー入門』、P54</ref>。
=== その他の開発順序 ===
==== チュートリアルの細部は後回し ====
:※ 特に出典は無いですが、技術系の仕事では常識的な考え方です。
RPGやシミュレーションゲームなど、プレイヤー視点では、ゲームの始めのほうに操作説明などのチュートリアルのイベントがありますが、しかし、実はチュートリアルの細部は、作るのが後回しになる場合が多々あるかと思われます。
なぜなら、ゲームで仕様を変更するたび、チュートリアルも変更の必要が生じるからです。このため、チュートリアルのとりあえずの完成の時期は、けっこう後回しになります。
よほど仕様の単純なゲームなら別ですが、そうでない場合、あまり開発初期からチュートリアルの細部を作りこみすぎないようにするほうが安全でしょう。
そもそも、チュートリアルをゲーム本編に組み込み必要もありません。たとえば説明書などで、細かい説明を代用する事だって可能なわけです。
チュートリアル部分に深刻なバグが発生してないかとか、逆に本編ゲーム中にチュートリアルが異常起動しないかなどの確認のために、開発初期からチュートリアルを組み込んでも構いません。ですが、おそらく、最終的なチュートリアルの完成時期は、仕様やゲーム全体像が本当に完成・確定したあとの時期なので、ゲーム本編の完成間近の時期になるか、もしくは本編完成後になるでしょう。
== 古典ゲームと技術限界 ==
ゲームを作る際、過去の名作ゲームを参考にしようと思うでしょうが、
しかし過去のゲームの設計は、当時の性能の限界に影響を受けているので、
果たして現代のコンピュータ性能の飛躍的に上昇した時代でも過去の設計をそのまま参考すべきかは、
やや検討の余地があるでしょう。
歌舞伎などの古典技芸の伝承の格言で『師を見るな、 師が見ているものを見よ』という教訓があると言われています。
このセクションでは、主に1980年代のファミコン時代のゲームを例に説明します。
=== スプライト ===
ファミコン時代の昔のゲーム機には、一画面に表示できるキャラチップ数(敵チップも含める)に上限がありました。
一画面中に表示できる限界は、だいたい、マリオが一画面中に数十人ぶんです。(実際の数値については、本ページでは触れない。説明の本質には関係ないので。)
ファミコンでは、このような仕組みを 「スプライト」と呼んでいました。(実はマリオ1体の表示の時点で既に、いくつかのスプライトの小単位を合成したものになっているのですが、説明やややこしくなるので、このページでは触れません。)
ともかく、実は昔のゲームのステージ設計は、スプライトの制限を前提にしたものになっています。
極端なハナシ、もしたとえばシュテイングゲームなどで、動く敵100体をボムで一瞬で倒せるようにしたゲームを設計しようとかファミコン時代に思っても、
ファミコンではすでに敵100体の表示の時点でグラフィック性能的に原理的に無理なのです。
どうしても敵100体を表示したい場合、表示のタイミングを変えます。
たとえば、
:1タイミング目では0~10体目までのAグループを表示、
:2タイミング目では11~20体目までのBグループを表示、
みたいにして、タイミングを変えることで、なんとか表示するのです。
このため、画面上に動くキャラクターが多いと、一瞬、ほかのキャラが消えるのは、裏側でこういうタイミング切り替えの処理が行われているからです。
説明の都合上、本ページではキリのいい「10体目」までと 上記の例では表現しましたが、実はファミコンの制限はもっときびしく、横1列上には8体目までしか表示できないと言われています。(しかもマリオ1体自体が、じつは2体×2体の計4体チップを使っているといわれる。なのでマリオ5体は同一ライン上には表示できない。)
なおシューテイングゲームの場合、敵チップだけでなく、敵味方の双方の弾丸もチップを利用しますので、実際の制限は上記の数値例よりも、もっと厳しいでしょう。
また、プレイヤー視点ではキャラクター1人にしか見えていなくても、背の高いキャラクターなどはキャラクター2体以上に相当するなど、注意しなければならないこともあります。
だからファミコン時代のアクションゲームで、巨大ボスのいるステージでは、ボス以外の敵が出現しないのは、おそらくですが、プレイヤー視点では1体のボスに見えても、内部プログラム的には敵チップを何体ぶんも利用しているのでしょう。
しかも巨大ボスは、ゆっくりとしか動きません。
おそらく、そのゆっくりとした時間内にVRAMを書き換え中だったのでしょう。
日本ではコトワザで「ウドの大木」みたいな言葉があるので、なんとなく巨大ボスがゆっくりと動いても不自然ではないかもしれませんが、よくよく考えたら現実世界の大男はけっこう動きが早いです。(レスラーやヘビー級ボクサーなどを考えれば分かるでしょう。)
=== 書き換え速度と背景グラ ===
ファミコンのマリオでは、書き換えの手間を省くために、一説には、たとえばマリオ1の地上ステージの世界の空の青色は、実はほとんどの場合、マリオが横スクロールしても空の青色の部分は書き換えをしておらず、横スクロールする前の青色をそのまま使いまわしていると言われています。
なぜそれで効率化できるかというと、ステージ中の障害物はほとんどのステージの場合で、画面の比較的に低い位置に障害物があるので、その低地の障害物だけを書き換えすれば済むからです。
だからファミコン時代では、こういう理由から、ステージの背景グラフィックや、障害物配置なども決まっているでしょう。
だから果たして、現代でもそれを過去の名作のステージ構成を踏襲すべきかどうかは、分かりません。もちろん、仕組みを分かった上で真似るのなら、それは特に問題ないでしょう。
=== アナログテレビの にじみ ===
ブラウン管では、細かすぎるドットは表示が、にじみます。ゲームに限らず、テレビアニメや一般の実写番組などでも同様、にじみます。(どのように、にじむかは、専門的なので説明を省略する)
だから、ファミコン時代から、だいたいプレステ1時代のゲームのグラフィッカーは、このことまで意識してドットを描いているはずです。
ともかく、液晶テレビとブラウン管テレビでは、同じ画像データでも表示結果が変わります。
レトロゲームから勉強する際は、ファミコン〜プレステ1時代のレトロゲームでは、データ上の解像度よりも実際のディスプレイ上の映像は細かいことに気をつける必要があります。
たとえば滲み(にじみ)を意図的に利用することでテレビの解像度以上の表現をしていたりしていました。
また、ファミコンのドットは縦横の長さが縦方向と横方向とで長さが違うので、そこまで考慮して、グラフィッカーは絵を描いています。
また、ドットの図形的な細かさだけでなく、色についても、にじみによって、当時のゲーム機の色用のビット数の限界を超えた表示をファミコン時代から行っていました。
つまり、同じドットの黄色の単色でも、そのドットの幅が1ドットか2ドットかで、テレビ上で表示される色が違います。「色が違って見える気がする」ではなく、実際にブラウン管のディスプレイ上では色が違うのです。言い方を変えると、ブラウン管テレビでは元の画像データ通りには色は表示されていません。(さらに縦方向と横方向とで色のにじみ方が違うが、専門的すぎるので、説明は省略する。wiki書くために調べるほうも大変なので。)
なので、もし現代の人がファミコン当時のゲーム作品のグラフィックを参考にする際は、このことに気をつける必要があります。一番、手軽なのは、そもそもグラフィックの細部については参考にしないことです。
これはつまり、もし公式エミュレーターなどでファミコン時代の古いゲームを、現代の液晶ディスプレイ用のゲーム機でプレイしても、エミュレーター側で過去テレビのグラフィック特性の再現のための特別な工夫をしてないかぎりは、実はグラフィックの表示結果が当時のものとは異なるわけです。
一方、パソコン市場では、ノートパソコンの普及し始めた1999年頃には液晶ディスプレイのものが比較的に安価で出て来たので、この頃からパソコンゲーム市場では次第にブラウン管のにじみを考える必要が無くなったでしょう。
なお、アナログテレビはそもそもテレビ自体の解像度が低いので、プレステ2時代あたりからのゲームには合いません。だから、プレステ2時代あたりからは、あまりブラウン管の特性を考える必要はなくなります。
逆に言うと、あまり指摘されないことですが、プレステ2時代の当時の人が当時の最新ゲーム機をプレイするには、もし既存のアナログテレビを使い続けていた家庭は、テレビ受像機そのものを買い換える必要があったという亊です。
一応、家電量販店などでテレビ用のアナログ/デジタル信号の変換機などを購入してテレビに接続するなどして使えば、デジタルテレビ用のゲーム機もプレイ可能ですが。
だからアナログ放送自体は2010年くらいまで続いたとはいっても、あまり当時のゲーム機をアナログ用テレビでプレイしていたとは考えにくくはあります(プレイヤーの好みによる)。
アナログ停波以降の時代である2010年以降の現代では、もうテレビ番組の受像でもブラウン管は一切用いられていないので、もはや現代のコンテンツ制作では特に考える必要はありません。
ブラウン管自体のドットの縦横が違っている。
このため、ブラウン管を前提にしたゲーム機やパソコンはそれに対応するために画像データ側のドットの縦横比が違っている。
ゲーム機やパソコンの種類、さらにはアーケードゲームの基盤といったハードウェアの種類ごとに、コンピュータ側でのドットの縦横比の管理は違っている(らしい)。このため、移植のたびに、ドットは書き直しになったようだ。
古いゲームの制作では「ドット用紙」という方眼紙のような印刷書面がある(らしい)のだが、そのドット用紙の時点で1マスの縦横比が少しだけ違い、1マスが長方形である。1ドットだけでは長方形であるのに気付かないかもしれないが、しかし「ちりも積れば山になる」ように、何十や百ドットも積み重なれば、縦横の長さは大きく違ってくる。
現在のパソコン用のドットエディタ(という画像制作ツールがある)は1ドットが正方形であるが、しかしファミコン時代は1ドットが(ドット用紙の時点で)少しだけ長方形である。(なお、画像制作ツールそのものの作り方については、『[[ゲームプログラミング/画像ファイルの作成プログラム]]』で説明する。ゲーム制作では普通は必要ないが、知識として。)
ファミコンの色数制限は52色から4色×4パレット(1パレットあたり4色)を使えると言われている<ref>[https://mynavi-creator.jp/blog/article/history-of-2dcg-designer
『2DCGデザイナーなら知っておきたい2DCGゲームの歴史』 2017/8/21 マイナビクリエイター編集部 ] 2021年12月30日に確認. </ref>。しかし実際には、4色のうち1色は透明色として利用される色であり、全パレット共通の色である(なので3×4=12色になることのいなる)。スプライトのパレットとは別に背景のパレットがあるので実際には、もっと16色以上の多くの色数が一画面内で使えるが、しかしその他のさまざまな制限があるので、合計で一画面内で25色が使えると言われる(12 × 2+1 = 25)。
しかし実際には、ブラウン管の滲み(にじみ)を利用しているので、当時のプレイヤーには1パレットだけで描かれた1キャラのキャラチップ内でも3色以上の多くの色が見えているだろうし、画面全体でも25色内にない色がプレイヤーの目には映っていることになるし、もしかしたら52色にない色がプレイヤーには見えているかもしれない。なお、スーパーファミコンの色数制限は32,768色から16色8パレットであると言われている。
レトロなゲーム機では、さらにメモリ容量やストレージ容量などの制限もあり、けっして仕様上の最大色数を気軽に利用できたわけではないだろう。こういう制限もあったからか、ネットではファミコンの色数が「4色」やら「8色」、スーパーファミコンの色数が「16色」や「256色」などとも言われることもある。
{{コラム|「ドット絵」とは|
よく世間には、ファミコン時代のゲームの、ゲーム中での絵柄のことを「ドット絵」という人がいます。プレステ1やセガサターンのポリゴンによって、「ドット絵」が無くなったと思っている人もいます。
しかし現実には、プレステ以降でも、顔ウィンドウの顔グラフィクや、キャラチップなどのグラフィックでは、その制作時にドット単位のグラフィック指定は行われています。
たとえば装備品で武器の横に小さい剣の絵などのアイコン画像が書かれている作品などもありますが、こういったアイコン画像もドット単位の指定で描くでしょう。
こう指摘すると、「プレステ1以降のゲームは解像度が高い」とかよくわからない反論をする人がいますが、しかし「ドット」という工学用語のどこにも、「解像度が低い」とかの意味はありません。また、「ドット」というのをブラウン管ディスプレイの映像だと思ってる人もいます。
しかし、液晶ノートパソコンの普及した2001年以降の液晶モニターの時代ですら、
「液晶のドット欠け」などのように「ドット」という用語は使われます。
「ドット」というのは、けっしてゲーム用語ではなく、「液晶のドット欠け」のように電子工学などですでに意味が決まっているので、ゲームオタクの戯言(ざれごと)は「ドット」の意味には無関係です。
さて、プレステ1以降のゲームでもキャラチップなどでは、ドット単位の指定が行われるのでした。
それどころか、携帯ゲームソフトでは、ガラケーの時代から既にドット単位の指定は現役の手法であり、スマホゲーム時代の現代でも現役です。
だから「ドット絵には魅力がある」とかいって、ファミコン時代のゲームばかりあげる人は、こういう現役のドット絵作家の努力が目に入らない人ですので、なるべく信用しないほうが良いと思います。
また、画像編集のフリーソフトまたはシェアウェアで、現代でも「ドット エディタ」と呼ばれる種類の画像制作ソフトがあり、少なくとも2D同人ゲームの制作ではよく使われます。
ツクールやウディタのドット絵を作る場合でも、ドットエディタを使って作るわけです。
ゲームに興味なさそうな人が「ドット絵」をレトロゲームの絵という意味で使うのは仕方ないかもしれませんが、しかしゲーム通みたいな顔して「俺ってけっこうオタクなんだぜ」みたいなフリしてるのに、レトロ的な用法で「ドット」という言葉を使う人はアレです。
おそらく、本当はけっしてドット絵が好きなんじゃなくって、単に自分の子供時代の思い出が好きなだけだと思います。
ニュアンスは違いますが、アニメ評論でもそういう話があります。1990年代後半に岡田斗司夫と誰かの対談で(おそらく書籍『マジメな話』での対談)、
「アニメの黄金期はいつか?」というよくあるアニメオタク談義について、
対談相手が言うには、
よく「70年代だ」「いや80年代だ」とかで議論が始まるが「いや12歳だ」というオチが有名だと。
}}
=== アナログテレビの焼きつきなど ===
あまりゲーム評論では指摘されないのですが、
このほか、ファミコン時代はテレビ受像機がアナログのブラウン管ディスプレイなので、
あまり長時間、同じ色をディスプレイ上の同じ位置に表示し付けていると焼きつきが起きる可能性があるので、
ステージごとにコンセプトになる背景色を変えたり、
あるいはステージの背景色を黒にしたステージを増やしたりとかの工夫も、必要だったかもしれません。
ゲームではないですがパソコンソフトなどの古いソフトは、こういったディスプレイの焼きつきの事を考えており、だからスクリーンセーバー機能の搭載など何らかの対策をしています。
ともかく、あまり、特定の色ばかり続けて使いすぎないようにする工夫が必要だったでしょう。
アナログテレビは西暦2010年のアナログ停波する時代まで使われていたので、焼きつき問題はファミコン以降のプレステ1~2時代のゲームにも関係するでしょう。
ネット上にはデマで「ブラウン管だと焼きつきが起きない」(×)というデマがあるが、しかし西暦2001年くらいの筐体パソコンのモニターはまだブラウン管が多かったし、その時代からすでに焼きつき防止のためにスクリーンセーバーがWindowsに搭載されていた。だからデマ「ブラウン管だと焼きつきが起きない」(×)にダマされないように。
なお、現代のテレビ受像機には、焼きつき防止のためにすでに「ピクセルシフト」という機能があって、
これは画面上の映像の表示位置をタイミングによって微妙にズラす機能です。こういう機能がすでに搭載されているので、わざわざゲームソフト側で実装する必要はない。そもそも液晶モニターは、焼きつきが起きにくい。ただし有機ELはどうだか、まだ新しい技術なので分からない。
== 脚注 ==
<references />
== 関連項目 ==
* [[ゲームプログラミング/コンピュータゲームの種類]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
* [[プログラミング]]
* [[w:ゲームプログミング]]
{{DEFAULTSORT:けえむふろくらみんく}}
[[Category:ゲーム]]
[[Category:情報技術]]
{{NDC|007.64}}
976y1byezsj8nyp5x1ic0rf84ifh37l
205837
205801
2022-07-25T11:48:55Z
Honooo
14373
/*機能の整備*/
wikitext
text/x-wiki
<div class="pathnavbox">
* {{Pathnav|ゲーム}}
* {{Pathnav|工学|情報技術|プログラミング}}
</div>
== 概観 ==
このWiki参考書では、コンピュータを用いた[[w:ゲーム]]のプログラミングを扱います。つまり、いわゆる「テレビゲーム」や、[[w:コンピュータゲーム|コンピュータゲーム]]に関する記述についてです。
ここでは家庭用のパーソナルコンピュータで扱える範囲の事柄、それらのゲームソフトをつくるためのプログラミングについて議論します。必要に応じて家庭用ゲーム機の話題にも触れますが、あくまで派生的なものです。本書はプログラミングの教材であるので、大多数の読者が最初にプログラミングで触れるであろうパーソナルコンピュータでのプログラミングを、特にことわらないかぎりは想定しています。
用語に関して、コンピューターゲームの世界独自なものもあるでしょうから、適宜『[[ゲームプログラミング/コンピュータゲームの種類]]』などを参照してください。
== 本書の目的 ==
この教科書『ゲームプログラミング』の目的は、題名にもあるとおり、プログラミングによってゲームを作るための技術の参考資料を目的としています。
ゲームクリエイターやゲームデザイナー(絵描きではなくゲームの設計者のこと)のためではなく、プログラマーのための教科書です。
したがって本書では、ゲームとは関係の少ない一般IT企業での仕事のしかたについての記述もあれば、製造業系の組込ソフトなどに関する概要的な記述もあります。
なぜなら本書はゲームクリエイターではなく、たまたま何らかの理由でゲームを作っているプログラマーのための教科書だからです。たとえゲーム会社を退職しても、他の一般IT企業に転職してもプログラマーとして応用できることなども目指して本書は書かれています。
従って、紹介する話題が、かなりIT系、テクノロジー系の話題に片寄っています。本書で紹介するクリエイター論やデザイン論は、派生的なものにすぎません。
;本書を扱う上での注意点
特にことわりのないかぎり、本書ではC言語でのプログラミングによってゲームを作りたい読書を念頭に説明しています。
だから、ゲームの生産効率性を無視してでも、本来ならRPGツクールのような開発ツールを使ったほうが早いシンプルなゲームの場合ですら、本書ではC言語または他のプログラミング言語での開発にこだわった方法を説明している場合もあります。
;その他、本書について
このページとそのサブページだけを見ていると本書は「ゲームクリエイトの教科書かな?」と捉えられるかもしれませんが、
しかしこのページとは別に本wikibooksには「[[プログラミング]]」というページがあり、そこではC言語やJavaなど代表的なプログラム言語のwiki教科書にリンクしています。ゲーム限定の話題ではないですが、プログラミングのコードについても、そちら『[[C言語]]』や『[[Java]]』やなどの教科書のほうが(実際に動作するコードの量が)充実しています。また、Visual C++ での画面出力については『[[Windows API]]』に入門的な説明があります。
本書『ゲームプログラミング』はそういったプログラミング教科書一覧の一部でもあります。C言語やWindows API の教科書では、これをどうやってゲームのプログラミングに応用すればいいか説明できないので(本wiki『[[C言語]]』はけっしてゲーム目的のページではないので)、ゲームの実際としてプログラミングの話題を切り離すために本書『ゲームプログラミング』は存在しています。
なので本書にゲームデザイン論やクリエイター論などの内容の充実は期待できません。
本書『ゲームプログラミング』は現状、プログラマー目的以外には対応できないかもしれません。もしプログラマー目的以外の無料のwiki教科書が欲しい方は、現状では、自分で本wikiに加筆するか、あるいは本書『ゲームプログラミング』とは別に新規Wiki執筆を検討していただきたい。
== ゲームを作りたいな、よし、ゲームを作ろう。でも… ==
===しかし自分の本当の目的ってゲーム作り?===
「ゲームを作りたい」と思ったのなら、まずはあまり細かい難しいことは考えず、実際に作り始めてみるのが一番いいと思います。もちろんプログラミングについてほとんど何も知らないのなら、ある程度の勉強は必要ですが、ある程度の知識があるのなら、プログラミングの技量や知識の充実を気にするよりは、実際にゲームの完成を目指してプログラムを書いてみるのが一番いいようですよ。その過程でプログラミングの学習や経験は積んでいけますしね。JavaScriptやPython、無料でプログラミングに取り組める環境も、今現在では充実しています。
しかし、ゲームをプレイするのが好きだからと言って、ゲームを作る、までが本当に自分が好きかどうか、試しに少し作ってみたら、少し考えてみるといいですね。
例えば読者の中には、「私はRPGがすき」という人も多いでしょう。
RPG が好きという事はおそらく、よくRPGの題材になる西洋ファンタジーのストーリーや世界も好きという場合が多いでしょう。そして一方で現実のコンピューターRPGで魅力的に提供される、イラストや音楽が好きという場合もあります。
実際のゲーム業界の人々も、ゲームを彩るイラストレーションや音楽がいかに重要な要素かを語っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P85</ref>。
さて、ここで問題なのですが、「ゲームを作りたい」と貴方が思っていたとして、あなたが本当に作りたいのはゲームなのか?あるいは本当はイラストが描きたかったり、音楽を作りたいのではないか?
…というのは、ゲームというのは総合的な分野ですから、イラストや音楽はその要素として確実にありますが、それ以外、プログラミングやシナリオなど、様々な創作や創造が必要で、全ての作業量はかなり多いものになるでしょう。
そしてゲーム、コンピューターゲームにはゲーム独自の世界観があって、現実や小説や映画とは違う、独特の法則に支配された世界を作る必要があります。ある意味リアリティを持たない、リアリティから外れた世界です。だから、小説のようなリアリティにこだわるなら、ゲームは不向きかもしれません。
ゲーム作り始めの時点では、これらの判断は明確でなくても勉強目的でも構いませんが、しかその内「自分は本当にゲームを作りたいのか? Yes or no?」という疑問への答えが必要になるときがくるかもしれません。
試しにゲームを作ってみて、もし自分の本当の目的がゲームでないと分かったなら、それ以外の活動に移るのも、取る道の選択肢でしょう。
;給料は安い
職業として、商売としてゲームを作る場合、ゲームプログラマーの給料は洋の東西を問わず、安い事が知られており、書籍などでも言及されています。たとえば『CAREER SKILLS ソフトウェア開発者の完全キャリアガイド』(ジョン・ソンメズ 著)という欧米人のプログラマーの書いた本には、アメリカのゲーム業界ですらハードワークの割に賃金が低い事が記載されており、もし給料の高い仕事につきたいならウォールストリート(※米国の金融ウォール街のこと)のための仕事をするべきだと書籍中で指摘しています。
日本でも同様にゲーム業界の報酬が低いことは知られており、多くのゲーム会社の伝記漫画でも、よく語られています。
アニメーション業界と比べたら、ゲーム業界のほうが報酬が高いことは事実かもしれませんが、これは実は恐ろしいことに、アニメーション業界の報酬が異常に低いだけで、アニメーション業界よりはましだけど、結局は…というのが現状でしょう。
=== 同人ゲーム以外の発表の場 ===
2001年ごろの日本はネットを活用した同人ゲーム黎明期、フリーゲーム黎明期で、実験的な時代でもあり、多くのイラスト愛好、創作者や音楽創作者がゲーム制作に手を染めていたようです。この頃、まだイラスト投稿サイトや小説投稿サイトといったものは無かったか、あったとしても小規模でマイナーなものでした。
しかし2010年のあたりから各種の投稿サイトが普及したことにより状況は変わり、むしろ現在では、小説やイラストを発表したい人はそのジャンルの投稿サイトに直接アクセスしたほうが早く、そのためゲームを通して発表するのは人によっては廻り道かもしれません。
それをわかったうえで、それでもゲーム制作に身を投じるかを考えた上で、「よし、自分はゲーム制作をしよう」と思えるなら、ゲーム制作をするのが良いでしょう。
実際、今現在の作曲家やイラストレーターは、ゲームに関わったとしても、専門家として楽曲やイラストを提供するという立場に過ぎない場合もあり、自分自身が主体になってゲーム制作をする人は、プロアマ問わず少数派のように見えます。
同人ゲームの世界でも現在は(2021年頃に記述)、プログラマー系の作者が圧倒的に多い様です。
しかし、専門外の人だからこそ、メディアミックス的な意外な視点で新しいものが作れる可能性もあるかもしれません。コピーライター、作家の糸井重里が、マザー2の企画にたずさわった例もあります。しかし、あくまで「可能性」であり、成功はけっして保証されてはいないので、読者の自己責任でお願いします。
今現在のゲーム専門学校のカリキュラムはプログラミングが主体です。CGの授業は、週に2時間程の様。一方でゲームCG、或いは、一般CGに特化した学科もある様です。
あるWikibooks編集者Aは、もしイラストを描きたいなら、イラストの世界で描くのが安全、と考えています。ゲームプログラミングについては、プログラムを書ける人は絵コンテも描けそうだし、基本的にある程度の作図的なイラストを描ける人は多いだろうから、別にプログラミングに専念しろとは思っていません。
さて、読者がゲーム制作を職業として目指すのかどうかはともかく、とりあえず、ゲーム業界の状況を知っておくのが有用でしょう。
結局商業界の状況が権威をもってその分野を支配しているのがこの社会の基本なので、趣味でも職業でも、業界周辺のことを知っておくのは得ることが多いはずです。
文献『レベルデザイン徹底指南書』では、現実世界で自分が新しいスキルを1つ覚えたら、古いスキル1つはどれか忘れる必要があることを説いています<ref>大久保磨『レベルデザイン徹底指南書』、2016年12月14日 初版 第1刷発行、P81</ref>。著者は、最初はグラフィッカーでしたが、しかしプランナーに転職したので、グラフィック関係の技能は仕事では「忘れて」しまった、という内容を述べています。ただし、比喩的に「忘れる」とは言っていますが、実際には忘却し無くなってしまったわけではなく、仕事では時間の都合により両立できないので、グラフィック関係の技能は例え話で「忘れた」、のであり、現実にはグラフィッカー時代に培った観察眼をプランナー時代の現在でも活用している、と、書籍中では述べられています。
このことは職業、あるいは技能とは一般的にそういうもの、と考えることができるでしょう。
{{コラム|漫画家大塚志郎のアドバイス|
同人ゲーム界では、ゲーム制作と、イラストまたは作曲などを一人で兼ねている作者も、ある程度は居ます。一方ネットの世界には様々な簡単に利用できるフリー素材もあるので、イラスト作画や作曲をしなくてもゲーム制作は可能ですよね。
一人でイラスト作画や作曲をしながらゲーム制作をするのはある意味マルチタレントだとも言えますが、現実にその創作をしている人たちは、かなり年長のこの分野の熟練者が多いようです。若い19歳ぐらいの頃に、それらマルチジャンルを両立するのは、一般にかなり困難なことだと思われます。
漫画家の大塚志郎は、漫画家を漫画創作の手本にするならデビュー時代を手本にするのが良い、と、漫画家向けの技法の教育漫画で語っています。
大塚は、漫画家の人生のうちで、これからデビューを目指している新人に近い境遇にあるのは、ヒット後の漫画家の生活状況ではなく、まだ無名・マイナーな時代の態度・生活だ、と描いています。成功後の熟練した漫画家より、若いデビュー直後の作家をお手本にするのがいいだろう、という主張ですよね。
さて、それでもデビュー時代から複数ジャンルの同人活動を均等に兼業する意思が硬いなら、それはそれでひとつの考え方ですが、上述のリスクを知っておく必要があるでしょう。
}}
===ゲーム業界は産業のエンジン役?===
かつてはゲーム産業が、日本のIT産業やデジタル家電産業の中心的・牽引(けんいん)役であった時代がありました。しかし、2010年以降、この考えは当てはまらなくなっています。
PlayStation2あたりまでの時代は、経済評論誌の未来予想でも、「もしかしたら今後、家庭用の据え置きゲーム機がパソコンの代替品として、家庭のリビング家電の標準品になるかもしれない」という予想があった。ゲーム産業がそのような牽引役として、経済界から期待されていました。ソニーが国産CPUをプレステ2〜3に搭載したり、WindwosのマイクロソフトがXBOXでゲーム機に参入したり、そういう時代です。
しかし2020年代の今は違います。結局、2020年代のゲーム機に使われてる技術や部品は、パソコン用の部品や技術の流用、ゲーム機のCPUも、今やインテルなどのパソコン用CPUをゲーム機でも使っています。
もはや現代は、ゲーム業界は、産業のエンジンではないようです。
ですから今現在、新しい技術に興味ある人は、ゲームにこだわらず、直接的にその技術を勉強し改良したほうが近道です。
たとえば、インターネット技術を使って何か新しい事をしたいなら、ゲームを作るよりもwebアプリやサーバーwebサービスを作るべきだし、目的のネットワーク用ソフトウェアをそのまま制作したほうが早いし確実です。
古い経済知識の先入観にとらわれず、無理にゲーム制作にこだわらないほうが、自分自身の技能やキャリアも開けていくでしょう。
2010年に出版された商学書籍『メイド・イン・ジャパンは終わるのか』には、「しかしながら、ファミリーコンピュータで世界に攻勢をかけ、その後圧倒的な強さを誇っていた日本の家庭用ゲーム産業も、90年代末からはその競争力にかげりがみえはじめた。日本の国内市場は伸び悩み、成長率は鈍化傾向にある(図表7-3)。」とあります<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.263</ref>。
その「図表7-3」の統計値によると、
:ファミコン発売の1993年には2268億円、
:スーファミ発売の1990年には2430億円、
:プレステ1発売の1994年には3882億円、
:1995年には急成長して4769億円、
:1997年には4795億円で、ほぼこの頃がピークであり、
:2000年には3768億円にまで低下(プレステ2の発売年)、
:2005年には3151億円まで低下(XBOXの発売年)、
である。(青島らが『レジャー白書』、『情報メディア白書』、『月刊トイジャーナル』、『CESAゲーム白書』などをもとに作成した図表の統計値です。)
<!-- ところで前編集者Sさん,これって正確には何の数字,金額なの?それを後で書き足しておいてほしいんだけど…。あれかな?一年のこの国のゲーム産業の売上高? -->
また、2010年の時点の商学研究では、1997年を境に、ゲームソフト市場で競争する企業数が増加傾向から減少傾向に転じた<ref name="m289">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.289</ref>、とも言われています。
書籍『メイド・イン・ジャパンは終わるのか』にも、引用文「家庭用ゲームは日本がその本格的立ち上げを主導し」<ref name="m91">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.91 </ref>と書かれているぐらいで、1990年代は日本のインパクトが強かったようです。
なお、携帯電話の分野で、日本は国際的な地位を喪失したのに対し、デジタルカメラとゲームは「現代」(参考文献の著作時2010年ごろ)でも日本が主要な地位にある<ref name="m91" />。
{{コラム|ゲームが産業の牽引役だと語った人物|
1998年頃、アニメ評論家の岡田斗司夫が、未来予想の一貫として、「これからゲーム機が、(パソコンではなく)家電の中枢になるだろう」というような内容の未来予想をしていました。たしか、岡田の著書『東大オタキングゼミ』(自由国民社、1998年)で、このような未来予想が読めます。岡田の東大での講義を加筆修正してまとめた書籍なので、実際の講義はその数年前に行われていたのだろうと思います。
岡田の東大での講義は東大生のその後の進路、官僚や大企業のビジネスマン達に大きな影響を与えただろうし、若手新進評論家として、この国の政治・経済人達も、その言論を参考にしただろう。
実際、2008年(リーマンショックあたり)くらいまでの日本の家電業界の投資は、ソニーがゲーム機のCPUを作ったりと、岡田の予想を参考にしているような面もありました。
ですが実際の2001年以降の家電業界の結果は予想とは少し外れました。まず
:* そもそも、冷蔵庫もエアコンも全然デジタル化(IoT化)されず、家電のほとんどが外部からのコンピュータ制御を必要としない状況。
:* 個々人が持ち歩いているデジタル家電は、携帯ゲーム機ではなくスマホになった。
:* パソコンは多くの家庭にいまだにインターネット用端末などとして残り続けている。
一方岡田は東大オタキングゼミで、98年当時の時点で任天堂が莫大な現金資産(たしか数千億円ほど)を持っていることに注目しています。
一般の大企業は、現金ではなく株券や不動産などの形で資産を蓄えています。しかし任天堂は、銀行口座の現金だけで数千億円という、非常に資金力の高い企業でした。今や日本を代表する世界的なゲーム大企業になっています。
また、日本だけでなくマイクロソフトのXBOXなど、実際に欧米の企業も昔はコンピュータゲームが産業の牽引役だと思って、先をこぞってゲーム機に参入していたわけでもある。岡田の未来予想は、決して根拠の無いものではなかったのです。
}}
{{コラム|読書について|
ゲーム業界と関連のない文献も、この教科書では出典として書かれていますが、これはこの頁の主要執筆者Sが、多量の市販本を読む以外に知的活動の方法を知らないことと、自分自身の文章の権威と信頼性を、著名人の威を借りて確立したいからでしょう。
ゲーム業界を志望するなら、ゲーム業界人の書いた本は少なくとも何冊かは読んでおくといいでしょう。
ネット上では、業界人ではないのにもっともらしく書かれた文章も多いですし、おそらく本Wikiの執筆者にも本格的なゲーム業界関係者は一人もいないでしょう。
業界人達のSNS発言ではなく、現代では書籍があるので、実際に書籍を手に入れて読むのがいいですね。書店で販売される書籍というのは、けっして著者だけの意見でなく、編集者や校正者、周辺の職業人達が査読をして、内容の信憑性を確認しています。
<!-- ニュース解説者の池上彰(いけがみ あきら)が、たしか2011年くらいのテレビ番組で言っていたことだと、編集者Sは言っている。 -->
何十冊も本を読むよりはプログラミングを書く実践のほうが重要でしょう。
『ゲームデザイン プロフェッショナル』著者であるFGOクリエイターも、ゲーム開発の書籍は読んでおくべきだと忠告しています<ref>『ゲームデザイン プロフェッショナル』、P234</ref>。また、ゲームデザイン本で学んだ知識は、ゲーム業界以外でも仕事術として活用できます。たとえば上司への業務報告の報告・連絡・相談(ホウ・レン・ソウ)などの考え方は、ゲーム業界でなくても活用できます<ref>『ゲームデザイン プロフェッショナル』、P332</ref>。
いっぽう、もし最新IT技術を勉強したいなら、読むべきは、ゲーム制作の解説本ではなく、そのIT技術の解説本など、そのものの書籍を読むほうが近道でしょう。
}}
===ゲームプログラミングは面白い。しかし、そんな楽な事ではない。===
ここでいう「プログラミング」とは、C言語などのプログラム言語による開発のことです。RPGツクールなど開発ツールによるゲーム制作の話は原則していません(本書『ゲームプログラミング』はあくまでプログラミングのための教科書です)。
さて、よくネットや、あるいは日常でも(C言語などによる)「ゲームプログラミングは簡単だよ。イラストやシナリオのほうが難しい。」、などという人がいますが、この発言の心は、「俺はプログラミングもイラストもシナリオも出来る凄い男だぜ。しかもプログラミングなんて簡単だし、むしろクリエイティブなイラストやシナリオの方に精力を費やす偉い奴だぜ^^」という、世間に良くいる武勇伝、自慢を語りたがる、インチキ親父が吹かしているだけなので、あまり真面目に取り合わないのが正解だと思います。
まず第一に、不当にプログラミングの価値を貶めている言説ですよね。
Visual C++またはVC# 、あるいは Direct Xなどを使ってプログラミングすることは、そんなに簡単なことではないでしょう。
ゲームプログラミングの入門書などには、初心者でも理解できそうな比較的簡単ないくつかのサンプルコードがありますが、それは初心者でも簡単に書けそうな技術だけを抜粋してるという、あくまで例外です。
RPGならたとえば、ドラクエ3のような戦争画面の行動順を処理するソート機能をつくるだけでも一苦労ですし、ほかにも道具・アイテムなどの自動整理をはじめとする標準機能を作るだけでも一苦労です。
決して上手い人のサンプルコードをコピーアンドペーストをして終わりという訳にはいかず(そもそも現状そのようなサンプルコードがネット上に無いですが)、もし仮にサンプルコードがネットに公開されていても、自作品に組み込む際にさらにそれをデバッグ(決してテストプレイの意味ではなく、実際にコード修正が必要になります)しなければならず、プログラミング言語の理解が必要です。
ゲームのプログラミングは決して楽ではないし、仮にもし楽だとしたら、じゃあゲーム会社のプログラマー職の人の仕事は何なんだ・・・という疑問につながりますよね(デマを言ってる人は、この疑問を脳内に都合よく無視しますが)。
ツクールやエディタのような制作ツールを使えば、C言語的なプログラミングは不要ですが、それはそのツクールなどのツールを開発している人達にプログラミングを肩代わりしてもらっているだけなので、決して「ゲームプログラミングが楽」、ではないでしょう。楽だというなら、じゃあツクール開発元の角川書店およびその発注先ソフトメーカーのプログラミングが楽だとでも言うのか・・・(デマを言ってる人はこの疑問を無視します)。
そもそもコンピューターゲームというのはプログラミングがなければ成立しないのですから、そのプログラミングの価値を貶めて平気な人は、コンピューターゲームにかかわる資格はないでしょう。
== ゲーム制作に関する留意点 ==
=== IT的な留意点 ===
====プログラミングなしでも同人ゲームを作れる====
自分でゲームを作る際、必ずしも、C言語などプログラム言語で記述する必要はありません。
プログラミングをせずに、ほぼマウス操作と会話メッセージなどの文章のキーボード入力だけでゲーム開発をできるようにするソフトウェアが、有料または無料で発表されています。
たとえば、RPGを作りたいなら、日本で発表されているソフトでは、『[[w:RPGツクール]]』や『[[w:WOLF RPGエディター]]』などのように、RPG製作に特化された開発ソフトがあり、大幅に開発の手間を減らせます。なお、『RPGツクール』は有料製品です。『WOLF RPGエディター』は無料ソフトです。
アクションゲームを作りたいなら、『[[w:アクションゲームツクール]]』があります。これらツクール製品は有料製品です。(なお、かつて『[[w: 2D格闘ツクール2nd.]]』というのがありましたが、しかし現在ではサポート切れのため、今現在の市販の十字キーコントローラーが初期設定では動かない、一部のボタンしか使えないなど問題点があります。)
また、ノベルゲームを作りたいなら、フリーソフトの『[[w:吉里吉里Z]]』などがあります。吉里吉里Zはソースコードが公開されており、オープンソースになっています。
:なお、とりあえず「ゲーム開発ツール」と呼びましたが、じつは呼び方は特に決まってはいません。「ゲーム制作ツール」と呼ぶ場合もあります。ゲーム開発ツールのことを「ゲームエンジン」と言う場合もありますが、開発ツール以外のゲーム用ランタイムのことも「ゲームエンジン」という場合があります。
:本Wikibooksでは、とりあえず、ツクールや吉里吉里シリーズやウディタ(WOLF RPGエディター)などのソフトの呼び方は、まとめて「ゲーム開発ツール」または「ゲーム開発ソフト」と呼ぶことにします。
C言語などによるプログラムは、上記のゲーム開発ツールを使わない場合の選択肢になるでしょう。
既存のゲーム開発ツールの仕様に不満を感じる場合に、「じゃあ自分でプログラムして作ろう」となり、プログラミングが必要になるわけです。
なお、上記の開発ツールはほとんどがWindows用のソフトです。MacやLinuxでは動きません。MacやLinuxで動作するゲームを作りたい場合は、別のソフトウエアを使う必要があります。
既存のゲーム開発ソフトを使わずにプログラムを組んでゲームを自作する場合、必ずしも既存のツールのような、ゲーム作品と開発ツールが分離された仕組みを再現する必要はありません。
一般的に初心者が、ゲーム開発ツールを作ることはほぼ不可能です。初心者は開発ツールを作ることは考えずに、まず1本、とりあえずゲーム自体を完成させてみましょう。開発ツールを自作したいのなら、まず先にゲーム1本を完成させたあとに、あとから開発ツールとゲーム作品の分離などに取り掛かるのが推奨です。
==== 商業ゲームの開発言語 ====
基本的に、現代の商業ゲームは、C言語で開発をする。
ただし、ファミコンの古いゲームは、アセンブラで開発されていた。ファミリーコンピューターからスーパーファミコンに至るまで、OSは搭載されていない<ref name="m289" />。
ではいつからC言語がゲーム開発に使われるようになったかというと、商学の学説では、プレイステーション(※ おそらくプレステ1?)の頃からだろう、と考えられている<ref name="m289" />。ただしこの時代でも、処理速度の高速化のためにアセンブラにアクセスする開発チームも少なくなかった<ref name="m289" />。
また、プレイステーションのOSは独自仕様である<ref name="m289" />。
カプコンなど一部の企業は、OSによる開発ではなく、移植性を高めるために自社製の内製フレームワークを用いて開発する。カプコンの場合、2010年頃は「MTフレームワーク」という自社製フレームワークを用いて開発を行っていた<ref name="m289" />。
{{コラム|ゲーム用のメーカー独自プログラミング言語について|
ゲーム開発ソフトには、ゲーム開発用の独自のプログラミング言語を持っている場合があります。このような機能の実現方法は、原理的には、ファイル入出力の関数を使い、テキストファイルの文字列を読み取って、文ごとにプログラム動作を設定・実行している、と、考えられます。インタプリタは、このような方法で作られています。
ゲーム製作ソフトでの独自のプログラミング言語はたいてい、コンパイル作業を必要としないので、おそらくインタプリタ方式でしょう。
基本的にWindowsの場合、実行ファイルに変換するには、Visual Studio というマイクロソフト社の配布している開発環境が必要です。
Visual Studio が開発環境を提供していない独自言語は、たいてい、インタプリタ方式となると思われます。
コンパイラ方式に比べて、インタプリタは処理速度が不利なので、適用できるジャンルや用途が限られます。たとえば3Dアクションゲームには、インタプリタ方式は不向きでしょう。
これらの独自言語を使うにしても、自分自身で独自言語を作りたいと思うとしても、この教本ではまず、既存のプログラミング言語を使ってゲーム制作を開始することを推奨します。
}}
====ゲームのプログラム言語の歴史====
ゲームを書くために利用される言語は多岐にわたっています。歴史的にはゲーム業界でも、[[C言語]]や、特に計算機のスピードが重要になる場面では[[w:アセンブリ言語|アセンブラ]]を利用してプログラミングを行うことが普通に行われていました。<!-- (文献)→-->そのため、ゲームプログラミングは通常のプログラミングと違った技能が必要であるように思われていました。
現在では計算機がある程度速くなったことや、ゲームプログラムの開発を複数人で行うことでテクニカルなプログラミングが避けられるようになったことにより、ゲームプログラミングは他の一般のプログラミングと同じような課題だと見なされています。
しかし、特にアクションゲームなどのリアルタイムでの画面書き換えが必要なゲームで、プログラムのスピードが重視されることは変わっていません。また、コンピュータの性能があがるにつれ、それらの性能を全て引き出すように表現手段が変化してきたため([[w:3次元コンピュータグラフィックス|3D]]、[[w:ポリゴン|ポリゴン]]などを参照)、状況によっては複雑で特殊なプログラミングが必要になることもあります。
===== 初心者が使えるプログラミング言語 =====
ゲーム開発において、一般にゲームショップなどで流通している商業ゲーム作品において、現在よく利用されているプログラミング言語として、[[C言語]]、[[CPlusPlus|C++]]、[[Java]]があげられます。
Windowsの3DエンジンのDirectXは、主にC++を想定しています。なので負荷の高いアクションゲームを作りたい場合、Visual C++での開発が安全でしょう。
しかし、ネット上のフリーゲームでは、C++以外の言語が使われることも、よくあります。
さいきんゲームエンジンとして有名なUnityは、言語としてはC#の文法を採用しています。
[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
市販の書籍では、Pythonによるゲーム開発を紹介した出版物もあります。ただし Python は原理的にインタプリタ方式であるために処理速度がC++に劣り、アクションゲームなど負荷の高いゲームを作る事を目指している場合は、将来的にはPythonからC++への装備変更が必要になるかもしれません。
===== ゲームに適さない(だろう)言語 =====
;Flash関係
例えば、かつて Adobe の Flash が、ブラウザで動かせるゲームを作る際に、よく使われていました。このようなwebブラウザ上で動くゲームのことを一般に、「ブラウザゲーム」と言います。ただし、現在ではFlashは廃止の方向です、すでにほぼ廃止されているといっていいでしょう。また、現状では、ローカルPC環境でのゲームをJavaScriptで作るのは、アマチュア段階では困難です。JavaScriptのアマチュアゲームと言う事例を聞きません。
;JavaScript
なお、JavaScript はクロスプラットフォームですが、しかし、セキュリティ上の理由などから、いくつかの機能(たとえばファイル入出力)がwebブラウザ上では使えないようになっており、そのため、JavaScript だけでゲームを作るのは、初歩的なゲームを除くと、かなり困難です。(おそらく、オンラインゲームでは、サーバー側でPHPやサーバサイドJavaScriptなどの別プログラムが走っていると思われます。)
セーブ機能の必要なゲームを作る場合は、JavaScriptでの開発は選択肢にない(セーブの実装には、JavaScript国際規格にはない非標準仕様を使いこなす必要があり、かなりの技術力を要するでしょう)。
=====ブラウザゲームの初歩的な原理=====
商品として流通するようなゲームや、高度な機能を持つブラウザゲームを作ることはとても難しく、このページでは手に負えません。そこで、このページでは、初心者が練習用につくるゲームを例に記述します。
webブラウザだけで動くのがブラウザゲームです。ブラウザゲームを作るのに使う言語の第一選択肢はJavaScriptです。サーバー側の処理が必要ならPHP,Python,Perl,Javaなどの言語の出番でしょう。
「ネットワークゲーム」は「ブラウザゲーム」とは意味が違います。
「ブラウザゲーム」は、パソコンにwebブラウザさえあれば、ネットワークに接続していなくてもゲームプレイできて、最後、クリアまでプレイできる作品もあります。
しかしネットゲームは、ネットワークに接続しないと、ゲームを開始することさえ不可能です。つまり、サーバの提供するゲームが「ネットワークゲーム」「ネトゲ」です。
もしPHPやPerlなどでゲームを作る場合、普通はネットゲームになる筈なので、作者がサーバを構築して提供する必要がありますし、プレイヤーにはゲーム中にサーバに接続する環境が必要になります。提供者は、サーバを用意したり、保守管理する必要がありますよね。サーバーがダウンしてしまうと、プレイヤーがゲームをできなくなります。
「PHP ゲーム」などの単語でネット検索したり、あるいは書店でプログラム言語の書籍や解説サイトを見ると、ときどきPHP・Perlなどの言語でゲーム開発しているものもありますが、一般的なダウンロード型のゲームとは違う筈なので、気をつけてください。
{{コラム|ソケット通信、ほか|
コンピュータプログラムからインターネットに通信するには、いくつかの方法がある。
C言語の場合はOSの提供するソケット通信といわれる機能を使う方法、
JavaScriptにあるHTTP通信の機能を使う方法、
などがあるだろう。
ただし、JavaScriptでゲームを制作するのは、セキュリティ上の制約などからセーブロードが標準的方法では困難など、とても制作が難しい。
よって本セクションでは、C言語にソケット通信を組み込むことの概要を説明する。
ゲーム制作初心者がソケット通信までする必要はないが、将来的には知る必要があるかもしれない。
本wikiではWindowsの場合については 教科書『[[WinSock]]』、
macやLinux / Unix や BSD の場合は 教科書『[[Unixソケットプログラミング]]』 で説明している。
Windowsとそれ以外のOSとで、ソケット通信の仕様が微妙に異なる。
ソケット通信では文字コードの問題がある。手元のパソコンの文字コード設定は、通信相手方の端末には反映されない。
Windowsの日本語版では、伝統的に Shift-JIS といわれる文字コードが使われてきたが、海外のWindows端末は日本の文字コードにあわせてくれないし、macやLinuxやBSDも同様に日本には合わせてくれない。
簡単な対処法として、ゲーム中では日本語を送受信しない、つまり半角の英数字と記号だけを送受信する、という道はある。
会員登録などのためにどうしても氏名や住所などの日本語を使う必要がある場合、PHP・Pythonなどサーバ言語に対応した「フレームワーク」があり、そのフレームワークが最初から日本語に対応、もしくは設定を少しいじるだけで日本語対応するので、それを利用すれば効率的かもしれない。
ゲームとは別途、サーバー側にフレームワークをインストールして、会員登録時にサーバー側でそれを使うようにすればいいだろう。
しかしゲーム内では日本語の扱いは非常に難しい、限定されるという事になるだろう。
C言語のプログラムにサーバサイドの言語・システムを組み込むのは難しいから、ネットゲームではどこかでソケット通信に頼ることになるだろう。
市販の本を探しても、そもそもソケット通信の書籍自体がめったに見当たらないし(ほんの少しだけ出版されている)、もし見つけても全く文字コードの問題の解決方法は紹介されていない(2021年現在)。
}}
====プラットフォ-ム====
;ライセンス料
一般に、プレイステーションや任天堂のゲームを開発するには、専用の機材が必要であり、そのため、ソニーや任天堂とライセンス契約しなければいけない<ref>『ゲームプランとデザインの教科書』、P.107 </ref>。
その契約に際して、ライセンス費用または料金と呼ばれるものを、ゲーム機開発会社の任天堂、ソニーに支払う必要があります。
現在でもソニーや任天堂のゲーム機用のソフト開発・販売には、ライセンス料が必要です。少なくともPS4やニンテンドースイッチのパッケージソフト開発には、「ライセンス費」が必要<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.120</ref>。
なお、書籍『ゲームプランナーの新しい教科書』によると任天堂やソニーのようにゲーム機を作っている会社のことをハードメーカーと言います。つまり、ゲーム機のハードメーカーにライセンス料を支払うという仕組みになっています<ref>『ゲームプランナーの新しい教科書』、P20</ref>。
また、スマートフォン向けアプリは、プラットフォーム使用料が掛かります。
書籍『ゲームプランとデザインの教科書』によると AppleStore, GooglePlayともに売上げの30%とのこと<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.121</ref>。その他のプラットフォームも、大体同じとのことです(参考文献の著作の時点では)。
Google やAppleのようにプラットフォームを提供している企業のことをプラットフォーマーと言います<ref name="gp244">吉冨賢介『ゲームプランナー入門』、P244</ref>。
昔からゲーム機のライセンス料は有料で高額であり、ソニーや任天堂の収益源のひとつになっている<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.267 </ref>。一方、パソコンゲームにはライセンス料が無いのが普通です<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.283 </ref>。
なお、ハードメーカーでなければプラットフォーマーでもないゲーム会社のうち、製造から販売までを手がける会社のことをパブリッシャーといい、たとえばカプコンやコナミやセガやスクウェア・エニックスやバンダイナムコなどがパブリッシャーです<ref name="gp244" />。
実は、必ずしもパブリッシャーが開発を手がけるとは限らず、スマホ向けアプリなどではディベロッパーといわれる開発専門の会社に委託している場合もあります<ref>吉冨賢介『ゲームプランナー入門』、P245</ref>。
;ポリコレ規制
Apple社のAppStore向けのスマートフォンアプリでは、アップロード後に、公開前にAppleによる審査があり<ref name="g139">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.139</ref>。、審査は欧米基準です。
GooglePlayは、公開前の審査はないが公開開始後に海外基準で審査されるので、それに違反していると配信停止になります<ref name="g139" />。
海外プラットフォームで販売・配布したい場合、「ポリティカル・コレクトネス」(政治的な正しさ)といわれる、海外の公序良俗の基準に配慮する必要があります<ref>『ゲーム作りの発想法と企画書のつくりかた』、P.235</ref>。
欧米の判断基準が、アジア諸国やアフリカの生活習俗に合致しない場合も多いのですが、欧米のIT大企業はその欧米基準での規制が政治的に正しいと考えているでしょう。「日本では、少し考え方が違う」と言っても、通用せず規制される場合も多い。
ゲームだけでなくテレビアニメでも、漫画ワンピースの海外アニメ版では、主人公側の若者がタバコを吸っているシーンをアメ玉に作画を変えられたり、ドラゴンボールに出てくるミスターポポという肌の真っ黒なキャラクターの肌を青く書き換えたり、色々な例があります。
ポリコレとは関係ない事例ですが、TVアニメーションのポケットモンスターで主人公のサトシ達がお握りを食べているシーンで、アメリカ版ではドーナツになっていたことがあります。これは、国による食文化の違いを示していますよね。
===プロトタイプ===
ゲームでは、曲や絵が良くても、ゲームとしては今ひとつ面白くない、という事は起こり得ますよね。
ですからむしろ、商業的なゲーム制作では、イラストは簡略なものを使ったうえで、プログラム中心の試作品(プロトタイプ)をいくつか作り、その中でゲームとしての面白さがあるものを、取捨選択したうえで商品化を考え、その後イラストや楽曲を詰めて完成度を高めていく、と、いう制作過程を取るようです。
書籍『ゲームプランナー入門』(吉冨賢介 著)によると、商業ゲーム界では、企画書に書かれたゲームが本当に面白いかどうか確認するために、「プロトタイプ」が作られます。プロトタイプの段階では、プログラマーと、企画の意図を考慮するためプランナーも関わります。<ref name="gp17">吉冨賢介『ゲームプランナー入門』、P17</ref>
イラストレーターは、プロトタイプの前段階あたりでイメージイラストを提供し、スタッフ間の共有イメージを作ります<ref name="gp18">吉冨賢介『ゲームプランナー入門』、P18</ref>。そしてプロトタイプ進行中は、グラフィック案の提案をしていきます<ref name="gcw56">蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P56</ref>。サウンドも同様、プロトタイプでは、曲調を固めていく段階です<ref name="gcw56" />。
:※時々あるトラブルとして、マイナーな同人ゲームや零細メーカーのゲームで、背景イラストや脇役キャラクターなど目立たない部分で他社のイラストが使われていることがあるようです。おそらく試作用に流用したイラストが、そのまま製品に混入したのでしょう。こういうトラブルがあるので、他社イラストの使用は試作であっても避けるべきです。
;実装検証
プログラマーは、そのゲームでコアになるプログラムやシステムやミドルウェアについて、プロトタイプ段階で実装検証を済ませておく必要があります。プロトタイプより前の原案の段階では、利用するミドルウェアの洗い出しをして、出来る範囲での基礎実験をしておきます<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P54</ref>。
ミドルウェアによっては使用料が発生するので、その点を事前に調べておく<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P55</ref>。
プロトタイプのうち、張りぼての例えば画面だけの物等を、「モックアップ」といいます。一方である程度遊べる状態まで作っているものを、「プレアブル」といいます<ref>STUDIO SHIN『ゲームプランナーの新しい教科書』、翔泳社、2018年3月10日初版第2刷、P251の図</ref>。
ゲームデザイン本ではよく「プロトタイプ」という表現が用いられるので、本ページではこの言葉を使うことにします。
{{コラム|商標権等|
知的財産権には著作権・商標権・意匠権などがありますが、商標権は特に強い権利であり、気を配る必要があります。
意匠権とは、建物や工業製品の外観に関する権利なので、ゲーム制作ではあまり気にする必要はないようです<ref name="gpd135">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.135</ref>。
「特許権・実用新案権」と「商標権」は、事業者によって国に登録されている権利で、かなり強力な権利なので、気をつける必要があります。
特許権や実用新案権とは、大まかに言えば、技術的な発明に関する権利です。商標が登録されているかどうかは、特許庁の『特許情報プラットフォーム』というwebサイト<ref name="gpd134">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.134</ref>で確認できます。
商標をトリッキーな意図で登録する人も多く、自社でビジネス展開をする気がなかったり、他社の商品などでまだ登録されていない物を申請したり、そういうやや不正な登録申請でも認可されてしまう場合も多いです。
また、商標は業種のジャンルごとに分かれているので、たとえば携帯電話のジャンルが新たに追加された時代に、過去のゲームの商標を登録した人がいました。そのため携帯ゲームを出せなかったり、商標を買い戻したり、取り戻すための裁判をするのに時間とお金がかかってしまったり、様々な問題が発生します。<ref name="gpd134" />
著作権は、登録の必要がなく、著作をした時点で発生する権利です。
『ゲームプランとデザインの教科書』によると、こういう事柄にまだ慣れていない人によくあることなのですが、他人の個人サイトやSNSで公開されていた絵や曲などを、許可なく勝手に使う事例があるようです<ref name="gpd135" />。
二次利用を許可されてない著作物は素材として使えません。
そして見落としがちなのが、フォントの著作権です<ref name="gpd135" />。フォントにも著作権があります。
フリー素材と書かれていても、商用販売が禁止されている配布形態のものもありますので、気をつけましょう。
}}
{{コラム|アイデアの権利。アイデアとは盗まれるのか、盗むのか?|
商業ゲーム作家たちの、2022/1時点でのSNS発言によると、業界全体でみられることですが、会社外部の人がアイデアを一方的に投稿してきて、会社で作った作品にそのアイデアと類似点があったら、アイデア使用料を要求してくる、そのような問題に悩まされているようです。
そこでゲーム会社側では原則、
:送られてきたハガキやメールは、まずクリエイター以外の事務系の人間が読む。
:もしハガキなどにアイデアがあった場合、そのハガキを処分。
などの方策を取ると言われています。
また、偶然や何らかの理由でアイデアが一致してしまった場合に備えてのリスク回避として、事前に会社のウェブサイトなどで「弊社にアイデアが送られてきた場合、そのアイデアは弊社のものになります」のような宣言をしている会社も多くあると言われています。<!-- (以上、作家のSNS発言やそれを紹介したサイトの取材などのまとめ.)←出典を消すなってS氏はやたら云うんだけど,そんな重要な事かね?もちろん全くなくて,いい加減な事書いていいと言ってるわけではないけど… -->
ここで前編集者は娯楽産業の世界には厄介な消費者がいると言及しているけど、この前編集者自身がこのWikibooks で異常なまでに厄介な参加者なんだが、そろそろ人のふり見て自分を返り見るべきだと思うな。
法学的には、著作権法はアイデアを保護しません(『アイデア・表現の二分論』と言います)。
そして前編集者はアイデアに関して権利をどうこう言う人間を無知だと書いているけど、自分は至上の賢人だと思ってるようだね。
そしてこの人物は他者を愚弄する時は必ず自分の意見ではなく、権威ある人がそう書いたから、出典だからと宣う。
出典は岡田斗司夫氏の著作『東大オタク学講座』や『マジメな話』だそうだ。
まあ岡田氏ならかなり過激なことを書くのは事実だろうが,この前編集者S はその悪徳をさらに10倍に高めてこのWikibooks に記述する地獄のように厄介で無知で馬鹿な人間だ。
}}
任天堂『ゼルダの伝説 ブレス オブ ザ ワイルド』は、プロトタイプの段階ではイラストや音楽を組み込まずに(イラストは、代わりに大きなドットの塊などで代用する)作られている事がゲーム業界見本市イベント CEDEC 2017 で公開されています<ref>https://game.watch.impress.co.jp/docs/news/1078888.html 2020年11月25日に閲覧して確認</ref>。
プロトタイプの段階では、画像や音楽は発注せず、骨組み的なプログラムだけで、そのゲームのアイデアが「はたして本当に面白いか?」を、実際に社内の関係者にプレイさせてみて確認します。
因みにプロトタイプに関しては『[[高等学校情報/その他の技術的な話題#プロトタイプ開発]]』の記述も参考になる。
ここでいう「プロトタイプ」(試作品)とは、コンピュータプログラムのゲームとして動作するのが前提です。映画製作でいう絵コンテ試写のように、ゲームの試作では、なるべく早期に第三者が試作ゲームを遊べるように作っていく必要があります。
プロトタイプという言葉を使用すること自体が妥当かどうか。まず、書籍『ゲームプランとデザインの教科書』で使われている<ref name="gpd350">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.350</ref>。
ニコニコ動画の経営者、川上量生が使っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日 第1刷発行、P.38</ref>。川上は角川書店も買収したので、おそらくそこ(カドカワ・RPGツクール販売元)でも使っているでしょう。
ゲームのプロトタイプの基本姿勢は、「汚く作って、やりなおす」です<ref name="gpd350" />。もちろん最低限のプログラムの知識、勉強は必要ですが、あまり知識収集や理解充実を気にするより、実際に作ってみることを優先したほうがいいようです。チーム制作をしている場合はプロタイプは赤ん坊であり、そのチームで育てていこう、我々の子供だという意識で接しているようです<ref name="gpd350" />。
勉強に関しては、汚くてもいいからまず工夫して作ってみると、何を勉強すればいいかが見えてきます。
英語では「quick and dirty prototype」という言葉があります<ref>川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.349</ref>。
書籍『ゲーム作りの発想法と企画書のつくりかた』によると、シナリオライター志望者が企画書やシナリオ案をメーカーに送りつけても、あまり効果的ではないようです。
それよりゲーム形式でシナリオを書いてしまうのがいいようで、「CHR:ヒロインA(私服)、表示」のような文章を織り交ぜて構成していくのが推奨<ref>『ゲーム作りの発想法と企画書のつくりかた、P.140</ref>。
参考文献のその章では、シナリオライター志望者に向けて語られていますが、プログラマーを目指すならどうすればいいでしょうかね。
プログラマー志望なら、サンプルゲーム、サンプルプログラムを作ってしまうのがいいかもしれません。
1990年代、週刊少年マガジンに不定期掲載していた読みきり漫画『ゲームクリエイター列伝』では、カプコン社のゲーム『バイオハザード』を扱った『バイオハザードを創った男達』の際、制作過程でゲームデザイナーが大幅な作り直しを判断して進行させた、という描写があります。(ただしWikiboooks一編集者の記憶、詳細はあいまい)。
のちの、ゲーム評論家の阿部広樹の評によると、むしろそれは劇的な大きな決断ではなく、ゲームデザイナーの日常の普通の仕事ではないか、と語られています。
どんな肩書の人間だろうと、すでに決まって進行していた方針をひっくり返すのは、かなりのストレスのある判断で指摘になりますが、一般に漫画や映画、あるいはNHKの仕事に関するドキュメンタリーでもそうですが、職業や職業者の物語では、過剰に対象を美化し、劇的な演出によって関係者を称賛し、英雄視する傾向があるように思います。
{{コラム|アイデアはアイデアで価値がある。でも、せっかくなら、それを試作して、形にしてみよう。|
ゲーム業界人広井王子は書籍のインタビューで、自分の社長としての人材評価は「0点」から始まる「加点法」だと語っていたようです。
『ゲームデザイン プロフェッショナル』著者も、文脈は違いますが「加点方式で物事を考える」と述べています<ref>『ゲームデザイン プロフェッショナル』、P224</ref>。
正直インチキなゲーム業界人の点数勘定などには全く興味ないが、そんな話とは全く別に、ゲーム制作の上で、実際に動く簡単なプロトタイプを作ってみることは間違いなく有意義な事でしょう。
アイデアはアイデアとして、思考や思想の展開としてありますが、それを具体的な形にしてみることは非常に楽しくエキサイティングで、意味ある活動ですよね。
}}
仕様書や設定資料を超えて、誰もが遊べる試作品は、意味のある企画行為でしょう。前編集者は、時間軸・動きの制作意図の明確化、という言葉を使っています。もちろん短くまとめること自体もなかなか難しいのですが、工夫を凝らして、ゲームプログラムを完成させることが重要な経験であり、思考の具体化でもあると思います。
===アルファ版===
アルファ版はプロトタイプとは違うもので、その後段階で、ゲームの全体像が分かる一部分を、商品に準じた形で作ることです<ref name="gp17" />。
アルファ版でもそのゲームが本当に面白いかどうか検証がなされます。サウンドやビジュアルは商品に近いほぼ完成化された形で取り込みます。
アルファ版の使用の結果、プロジェクト中止の決定がなされる場合もあります<ref name="gp18" />。
ベータ版とは、会社によって意味が多少違いますが(たとえば『ゲームデザインプロフェッショナル』と『ゲームプランナ-入門』とでも微妙に違う)、おおむね、とりあえずのゲーム、最初からエンディングまでのほぼ完成状態をひととおり遊べる制作物です<ref>『ゲームデザインプロフェッショナル』、P170</ref>。
細かいバグ修正はこれらの段階では後回しにします。
基本的に
:プロトタイプ→アルファ版→ベータ版→調整→デバッグ
の流れですね。
===プロトタイプ制作に必要な予備知識===
====数学は後回し====
ゲーム制作の作り始めにおいて、必要な数学や物理の予備知識は、それほど多くありません。
文献『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』によれば、数学や物理の習熟に拘って、それに多くの時間と精力を費やして勉強するよりは、3Dの勉強などで必要を感じたら、そのつど、その分野の数学や物理を学ぶのが効率的だと述べており、また可能なら実際にプログラミングでその理論を試してみると具体的に理解をしやすいと述べています<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P88</ref>。
====C言語の予備知識は入門書1冊+αで十分====
C言語を使ったゲームは、予備知識はそれほど多くないので、あまり難しいことは考えず、まず実際にプログラムを書いて作ってしまう事優先にするのが正解なようです。
市販のC言語入門書で、配列や関数などの一般的な機能を一通り習得したら、あとはVisual C++ で映像出力とキーボ-ド入力のみを、1~2週間ほど勉強、そしてVisual Studioを起動してゲームを作り始める。
うまくいけば数か月以内に、パソコン用の非ネット通信のゲームを作ることができるでしょう。
ただ、ゲームプログラミングを試みる人は、必ずしもゲーム制作のみが絶対的な唯一の目標ではない可能性もあるので、それぞれの立場に応じて、座学を取り入れてみるのもいいと思います。
== 作業リストを作る ==
===作業リストの制作開始の方法===
さて、ゲームを作る時は、アイデアを頭の中だけに置いておくのではなく、文章に書きだしてみましょう。
そして、壮大な長大なアイデアではなく、1週間~1ヶ月ていどで成果の確認できそうなアイデアだけを書いてみましょう。
次にそのアイデアを、実際に動作するプログラム、ソフトウェア(つまりプロトタイプ)にするために、具体的などんな機能を持ったプログラム(簡単なものでよい)を制作しなければいけないか、自分のやるべきことのリストを、箇条書きで作ります。<ref>https://www.youtube.com/watch?v=J5FCZG7dfEY 2020年3月17日に閲覧</ref>
IT界ではこういうリストを「ToDoリスト」(読み: トゥードゥーリスト)とか「タスクリスト」といいます。このページではむしろ日本語で、「作業リスト」と呼んでみましょう。
さて、このリストを作るときは、作業項目は具体的かつ単純な目標に分割します。ですから例えば RPG の戦闘システムを作るときは、
*「戦闘システムを作る。」
と、あいまいに総体的に書くのではなく、具体的に、
*戦闘画面のメッセージ表示欄および標準メッセージを作る。
*「戦う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは後回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
という風に、作業項目を細かく分割していきます。
こうすることで、作業がひとつずつ比較的に簡単な要素に分解されていくので、楽になります。また、バージョン管理ソフトを使って管理している場合も、上記のような作業リストの分解をしておけば、各バージョンの概要を書く際にも作業リストの項目が転用できるので、一石二鳥です。
予定日は書かないほうがいいように思われます。スケジュールを管理したい場合は、別にファイルを作るといいですね。
そして書き出した項目を優先順位で並べたら、最初の作業リストは完成です。
===作業リストの更新===
プログラミングする前に作業リストを眺めて、そして上の項目から実際に作業を開始しましょう。
そして一つの項目を完成させましょう。
そして作業項目がひとつ終わったら、「【完了!】」等、そういう情報を、項目の前または後ろにつけます。備忘のための記録ですね。
たとえば、
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
こうします。
以前の記述を残したまま、その作業が終了したことを示しておくわけですね。
また、もし追加の作業が必要になったら、たとえばダメージ計算システムを作るために、ランダム計算が必要になって、自分がそのプログラム言語でのランダム計算に詳しくないなら、たとえば
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
::※3行目に追加されています。
と、必要に応じて項目を追加します。
さて、これから行う作業を検索しやすくするため、たとえば
'''やることリスト'''
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
'''完了した作業'''
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
の様に完了した項目を後回しにしたり、或いは
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*(現在→) Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
のように、(現在→)、を追加するのも良いでしょう。
つまり作業の記述をそのままに、どこまで進展しているかが分かる等に書き足していくわけですね。
==プロトタイプ制作における創作面の検討事項==
===ゲーム性===
「ゲーム性」という概念があって、これがあるからこそゲームは面白く、魅力的だと考えられています。
プレイステーション開発元のソニーもこれを重視していますし、一般的に多くのゲーム愛好者、関係者たちもその考えに同意するでしょう。
ではゲーム性とは何か?
ゲームのジャンルにもよりますが、「駆け引き」や「戦術」、これが「ゲーム性」だとよく言われます。
『ゲームプランとデザインの教科書』によると、ゲーム性とは、シューティングやアクションでは「対戦の駆け引き」、RPGでは「戦闘と物語の介入」、シミュレーションゲームなら「戦略性」だそうです<ref>『ゲームプランとデザインの教科書』、P152</ref>。
ただし上述の書籍によると、1990年代は今よりもゲーム性とシステムが重視されていたとの説明があるので、裏を返せば2010年以降の現代では、ゲーム業界ではゲーム性の重視の比率は1990年代よりも減っているかもしれません<ref>『ゲームプランとデザインの教科書』、P302</ref>。
『ゲームプランナー入門』(吉冨賢介 著)では、ゲーム性とは「課題や挑戦の仕組み」であると結論づけています<ref>吉冨賢介『ゲームプランナー入門』、P36</ref>。そして、この達成感こそが「ゲームならではの面白さ」だと述べています。
;アクションパズルゲーム「I.Q」
メディアクリエイターの佐藤 雅彦氏(「だんご3兄弟」や「ピタゴラスイッチ」等を手掛けている)が、初めてかかわるコンピュータゲームで、ソニー・コンピュータ・エンターテインメントとの共同企画で、のちに「I.Q」(1997年にシリーズ第一弾を発売)と呼ばれるシリーズに携わった時、プロトタイプが全くゲーム性のないものになってしまい、それをプレイしたソニーの幹部陣の顔色が非常に曇ってしまったようです<ref name="br67">川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P.67</ref>。
ここでの悪い反応、薄い反応の理由がわからなかった佐藤氏が、階段の踊り場でソニーの新人に尋ねてみると、「それが、あの、ゲーム性がないっていうか・・・」と言われたと出典の対談集に書かれています<ref name="br67" />。
基本的に佐藤氏は、プロトタイプの企画を提案しただけですが、ソニーにはプロトタイプを作るための部署があるらしく、1~2ヶ月かけてそこでプロトタイプが作られたようです。
この問題の責任が誰にあるかは、大した重要な事ではありませんが、商業作品としてプロトタイプを作る以上は、どこかの段階でゲーム性を意識して、プログラムに盛り込む工夫が必要になるでしょう。
===ゲームの見た目とは?===
ふつうゲームのプレイヤーは、まず最初にそのゲームの「見た目」を判断し感受するでしょう。ですからその見た目のインパクト、興味を呼び起こす構成が必要になります。
例えばスーパーファミコンRPG『新桃太郎伝説』では、開発当初はドラゴンクエスト5 のようなマップ画面のトップビューUIでしたが、開発中にクォータービューの他社製RPGが発売されて高い評価を得たので、マップUIを(トップビューではなく)クォータービューに作り直したようです。このことは攻略本『新桃太郎伝説 究極本』に開発裏話として書かれています。
一方現在でもこの方向の試みは重要なようで、書籍『ゲームデザイン プロフェッショナル』の著者は、他企業の製品の画面と、自社の製品を目で見比べる分析方法で、自分たちの製品のUI の問題を見出しています<ref name="gdp199">『ゲームデザイン プロフェッショナル』、P199</ref>。
割と素朴で単純で即物的な見た目、「かっこいい」とか、「ぱっと見派手」等の要素が非常に重要なようです<ref name="gdp199" />。
商業としてゲームを作る以上は、ペイしなければ企業も事業の継続も維持できませんから、考慮せざるを得ない問題ではあります。
== ゲーム開発ツールを使う場合 ==
====開発ツールのライセンス条件====
ゲーム開発ツールのなかには、そのツールで開発したゲームソフトに義務として「この開発ツールで開発したソフトウェアは、ソースコードを必ず公開しなければならない」などの条件をつけている場合があり、このような条件を「開示義務」(かいじ ぎむ)または「ソース開示義務」などといいます。
ソース開示が嫌な場合は、開示義務のあるツールは使わないのが正解ですね。
ゲームに限らず、ソース開示を義務としている開発ツールは多くあるので、ライセンスには気を配る必要があります。
「有料ソフトの販売を禁止」とか「アダルト作品の開発は禁止」などの条件をつけている場合も、ありえます。
ですからゲーム開発において、ツールのライセンス条件の確認は、非常に重要です。
{{コラム|GPLライセンス違反|
GPL(ジーピーエル)というライセンスがあって、Linuxなどのオープンソースで使われています。このGPLを組み込んだプログラムは、ソースを公開しなければいけません。
ですから、ソース公開したくないプログラムには、GPLソフトウェアは組み込めません。
ゲーム業界でも、GPLライセンスのソフトウェアを組み込んでしまったために、呼出し元ソフトウェアでのソースコードの一部を公開することになったゲームがあります。2005年頃、『ToHeart2』という美少女ゲームが、xvidというGPLソフトを取り込んだ疑惑によって、GPL違反の疑いでソース公開になりました。([[w:ToHeart2#GPL違反とソース公開]])
GPLでも、たとえばLinuxサーバ上でソース非公開のアプリを動かすように、GPLのソフトウェアを非公開ソフトとは独立した状態で使う場合は、ソース公開の必要はない、と、考えられています。(これが必要有りとなると、オンラインのプログラムやネットゲームは全てソース公開しなければならなくなり、非合理な結果になる。)
特定のプログラム自体に、GPLソフトウェアのコードを取り込んだ時、ソースコード公開が必要になります。
}}
{{コラム|BSDライセンス他|
オープンソースの中には、どのような利用法であっても、利用者にソース公開を求めないライセンスもあります。BSDライセンスとMITライセンスはソース非公開で利用できます。
ゲーム制作ツールの吉里吉里Zは、修正BSDライセンスで公開されています。
もしライセンスのことがよくわからない、またはライセンスの学習に時間をかけたくないなら、オープンソースのツールを使うなら、BSDライセンスを使うのが安全です。
}}
[[w:DXライブラリ]]は、GPLでもBSDライセンスでもありません(DXライブラリ説明書「DxLib.txt」には、どこにも「GPL」とも「BSD」とも書いていない)。DXライブラリは単にソースコードが公開されていて、著作権者の「山田 巧」氏が著作権を保持しているオープンソースなライブラリです。
このように、ネット上でソース公開されているソフトウェアには、ライセンスの複雑な解釈を嫌ってか、「BSD」や「MIT」などのライセンス条件を名乗らないオープンソースソフトウェアもあります。
{{コラム|自作ソフトでソース開示|
昨今ではオープンソースやフリーソフトウエアの発展などの背景もあり、「自作ゲームのソースコードやソースファイルも開示しよう」と思うゲーム作者もいるかもしれません。
然しソースコードを開示していることが原因で、トラブルに巻き込まれる場合もあるかもしれません。自分の作ったゲームのコードが悪用され、トリッキーないたずらや嫌がらせ、誹謗中傷などを受ける可能性も全くないわけではありません。
そこでライセンスに、利用による損害に対する保証が無いことを明示するのは、ある程度有効でしょう。大抵の著名なフリーソフトウェアライセンスには、この条項があります。他者の悪意を完全に防ぎ失くすることは難しいのですが、ある程度の対策は見出されていますし、自身でも見出していく必要があるでしょう。
}}
====開発ツールを使用しないという事====
下記の理由(機能制限および移植性の悪さ)の問題から、あまり大規模な作品は開発ツールでは作らないでおくのが安全です。
大規模な作品の場合、Visual C++ などでコードを書いて開発することを推奨します。
=====機能制限=====
ゲーム開発ツールを使う場合、そのツールにもよりますが、「○○ができない」、つまり特定の目的を果たすための機能を持っていない場合があります。
Visual Basic や Visual C++ には普通にある関数でも、開発ツールには無い場合も多い。
また、もし、いったんはゲーム開発ツールを使って目的の機能を持ったシステムを作ったとして、さらなる機能をそのシステムに追加しようとするときに、大幅な作り直しが必要になる場合があります(拡張性の悪さ)。
システムがモジュール化されていても、そのモジュール部分では大きく改変する必要がある場合もあるでしょう。
ですからゲーム開発ツールによるゲーム制作では、あまり大作を作ろうとしないほうが安全です。開発ツールで作る作品は、比較的に小規模な作品に、とどめておくことを推奨します。
Windowsの場合、本来なら Visual C++ などを使って、プログラム文法のいろいろな事に留意しながらプログラムを書きますよね。開発ツールを使う場合、 Visual C++ のコードを書かずに、ほぼマウス操作だけでプログラムを作ろうとしているわけですから、何かしらの制限があります。拡張性の悪さは、プログラム文法などの学習の負担を減らすためのトレード・オフのようなものですね。
=====移植性の悪さ=====
また、もうひとつの問題点として、C言語への移植性の悪さがあります。
ソースコードが公開されていない開発ツールの場合、異なる開発環境にゲームのソースファイルを移植するのは、ほぼ不可能です(仮に、開発ツールのランタイムを模倣できたとしても、著作権などの法的な懸念が生じる可能性あり)。
ゲーム開発ツールで作ったソースを、Visual C++のソースに置き換えるのは、簡単にはできないし、ほぼ全面的に新たに書くことになるでしょう。
==イラストレーター、デザイナー==
ゲーム制作、業界において、イラストや音楽を作る部署、人物は、まとめて、"アーティスト"と呼んでいるようです。
ゲーム界の場合デザイナーというのは、プランナーやディレクターのことであり、管理職的な設計者のことで、美術的なクリエイターではない。design という英語には、機械建築の設計という意味もあります。
映像関係、画像系のアーティストはグラフィッカーと呼ばれることもあります。ムービー担当者、特にゲーム界では3D-CGの制作者をアニメーターと呼ぶことが多いようです。アニメーション業界では主に、手描きの原画、動画マンをアニメーターと呼びますが、最近は3D-CGアニメーション映画も多いので、すこし状況が変わっているかもしれません。
ゲーム業界とアニメーション業界、各会社企業、過去と現在で、「原画」「仕上げ」「絵コンテ」等、一般的な作業に関する言葉が、それぞれの状況で微妙に違った意味で使われることも多いですね。
…ところで前編集者はわざわざこの項目を作ったうえで、色々な場所での言葉の意味の違いを、クドクドと自分勝手な分かりづらい説明で長々述べた後、「混同しないように気をつけましょう。」なんて馬鹿馬鹿しい言葉で締めているんだけど、この人物の意図はどこにあるのだろう?
例えばデザイナーというのは一般的に、造形作品、図案、意匠を考案する人のことを言うのだから、ゲーム界の外の人間が多少その業界内での意味を取り違えても、それほど致命的なミスでもないし、罵倒、愚弄されるいわれもなければ、好き放題にその相手を罵倒、愚弄していいわけでもない。間違えて使っている人を見たら、その都度やんわりと教えてあげればいいだけじゃあない? だいたいその世界に現実に身を置いたら、そこでの言葉の意味、使い方なんて自然に覚えるものだし…。
それを得意げにこれが違うあれが間違いといちいち理屈書いて、いい気になって威張っているこの人物は何者なのだろう?
現編集者が思うには、この人物は、学問、知識、知恵、科学とは何かという事を、根源的に取り違えている、のだろう。
==操作性==
操作性について、親指と人差し指<!-- ←ここ,中指って書いてあったけど,こっちだよね? -->だけでボタンプッシュなどの操作ができるように作成するのが基本です。中指、小指、薬指はコントローラのホールドに使うぐらいです。人間工学的に、小指や薬指は力が弱いので、微妙な操作には向かないことが知られています<ref>川上大典ほか『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.48</ref>。
一般的にゲームプログラミングでは、
# プレイヤーからの入力を扱うことができる。
# ゲームが提示する内容を表示することができる。
入力と出力、この2点が機能として必要になります。
プログラミング言語とプレイヤーからの入力については歴史的にも、あまり変化がありません。言語では主に[[C言語]]、[[C++]]が用いられる。[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
パソコンゲームでは、プレイヤーからの入力には通常、キーボードかマウスを利用します。他に[[w:ジョイスティック|ジョイスティック]]や[[w:ゲームパッド|ゲームパッド]]が利用される場合もあります。家庭用ゲーム機では[[w:コントローラ|コントローラ]]が利用されることが多いのですが、[[w:ニンテンドーDS|ニンテンドーDS]]や[[w:Wii U|Wii U]]では[[w:タッチパネル|タッチパネル]]、[[w:Wii|Wii]]では複数の入力機器が提供されることが発表されています。各種入力機器をプログラムから扱う手法自体は、普遍性があり、入力機器ごとに大きく変化しない、と、考えられています。[[w:デバイスドライバ|デバイスドライバ]]、[[高等学校情報B]]には、プログラムから周辺機器を扱う方法について多少の記述があります。
画面表示のうち、3Dの表現は割合難しく、ある程度の数学(高校、あるいは場合によってはそれ以上)の理解が必要でしょう。2Dに関してはプログラムの面では、さほど難しい部分はありません。
==処理速度の問題==
基本的にプログラミングでは、関数を使って、処理をコンパクトにまとめ、定数ではなく変数で柔軟性のある操作をすることが求められますが、ゲームの場合は、この構造のせいで処理速度が低下することがあります。
現在のCPUの性能、速さはかなり高くなってはいますが、プログラム処理は無限に煩雑化できますから、やはり高度な処理を短時間でなすことが求められます。特にゲームは、リアルタイムの反応のタイミングが非常に重要ですからね。数学の指数計算についての雑学で、「新聞紙を42回おりたたむと、月に届く距離になる」というものがあります。(新聞紙の厚さ)*2^42、ですね。もっとも新聞紙の物性から言って、ほぼ不可能な操作ですけど^^;;。コードの内容、組み合わせによっては、このように計算量が指数関数的に膨大になってしまい、処理速度が非常に遅くなってしまう場合があります。
ですが、このセクションで後述するように、関数を用いる場合の解決策(※概要:あとでdefineやinlineに置き換え)があるので、プログラミングの初期のほうは、とりあえずバグを未然防止するために関数を活用するべきでしょう。
1980年代頃のファミコンなど古い時代のゲームでは、ストレージ容量(ハードディスク容量のこと)が、ボトルネックでした。「容量不足でイベントをいくつか削りました」と、当時のRPGなどのゲーム作家が述べるのは、ストレージ容量の不足のことですね。ただ当時のファミコンはROMカセットでハードディスクは無いので、まさにストレージ容量という言葉が適切でしょう。
しかし2010年以降の現代では、ボトルネックになっている要因は、ストレージ容量不足よりも処理速度です。
ゲームプログラミングに要求されるコード特性は、科学計算ソフトウェアや金融プログラミングなどの手法とは異なります。情報工学・情報科学で適切とされる「構造化プログラミング」などの歴史的に発展してきたプログラミング・パラダイムの理念とは反するようなコード開発方針になる場合もあります。しかしゲームプログラミングに限らず、限定されたハードウェアで特定の結果を速く得るためには、様々なトリッキーな手管が必要になるでしょう。
;ツクール等制作ツール
RPGツクールの制作元のカドカワ(アスキー社→エンターブレイン社→カドカワ(かつての「角川書店」) )では、PRGツクールでのアクションゲーム開発は推奨していません。アクションゲームの場合は、同じカドカワの「アクションゲームツクール」で制作するよう、薦めています。
アクションゲームとターン制RPG では要求される特性が大きく異なり、なかには、ほぼ対立しているような性質もあります。
ツクールやウディタでも、万能にあらゆることがスタマイズできるわけではなく、その制作ツールの特性に依存しますし、主に処理速度の低下しない部分についてユーザが創作できるようになっているでしょう。
多くのRPG制作ツールはマップ操作や戦闘画面の基本システムのルーチンそのものは、あまりカスタマイズできません。画像や音楽は挿入できますが、例えば戦闘プログラムなら、「コマンド」の命令文など一部の派生的な部分だけが独自に作れる程度でしょう。
ですから、ツクールでどうしてもアクションRPGを作りたい場合、基本システムの改造はかなり困難だろうし、別途、アクションRPGのような動作をするマップイベントを作成する・・・ぐらいでしょうね。
ツクールやウディタでターン制RPG以外のジャンルを制作するのには、実質的には限界があり、さまざまな制約が生じます。
;具体的な手法
初期段階では関数や変数を活用してプログラミングし、処理速度を高める必要がある箇所にだけdefineマクロ等を用い別の方法に置き換える。C++ならinline関数という前処理命令もあります。
通常の関数で記述していったソースコードを、あとから一括変換などでdefineマクロやinline関数などに置き換えることは比較的に容易です。
また、関数を経由しているので、マクロを使った場合でも比較的にバグが混入しづらくなっているかもしれません。(defineなどの前処理命令マクロは、用いるとバグを発見しづらいので、なるべくマクロの利用を避けるべきなのが、ゲームプログラミングに限らないプログラミングの定石です。)
一方、まったく関数を使ってないコードを、あとからdefineマクロなどに手作業で置き換えるのは、なかなか面倒です。
最終的には一括変換で置き換えることが出来ますから、途中の段階では、処理速度を気にせず関数を使うのがいいでしょう。
なお、defineマクロは、値の置換以外には用いないのが、プログラミングの定石です。このため、たとえば黒色RGB値の<code>10,10,10</code>といった配列にdefineマクロを使うべきかどうか悩みますが、とりあえずなるべく値周辺にだけdefineマクロを適用するようにするようにするのが良いでしょう。いっぽう、一般の命令文をdefineマクロで置き換えるのは、避けるべきでしょう。
たとえば、処理に0.5秒ほどの時間の掛かってもかまわないような場所は、どんどん、関数に置き換えていっても良いかもしれません。
アクション性のないゲームなら、関数をぞんぶんに活用できます。
ターン制RPGやシミュレーションゲーム、アドベンチャーゲームなど、関数を活用しやすいでしょう。
一方、アクションゲームなどでキャラクター操作中のコードのように頻繁に使って、しかもそのゲームの中心的なコードなら、そこは最終的には関数にしないほうが良いかもしれません。
このように、ゲームのジャンルによって処理速度に対する必要な水準が異なりますので、プログラミング時における関数などの利用の方針も異なります。
以上のように、何でも関数にすることは避けるべきです。関数は処理速度の問題がありますので、必要性のある部分だけ関数にするべき。関数を使わなくても、for文やif文などのブロックの構成を適切に組み合わせることで、コード中のmain関数以降の部分でコード共通化できることは色々とあります。
「共通性のあるコードだから」といって、大して長いわけでもないコードを関数に置き換える事は、速度維持には寄与せず、ゲーム制作のプログラミングとしては、悪手となるでしょう。
===2Dの画面出力===
画面出力の場合も入力機器の場合と同じで、これらを操作する方法はOSごとに異なっています。先ほどあげた GTK+, Qt, SDLなどのライブラリはクロスプラットフォームの画面出力を提供しているため、これらを利用することで全てのプラットフォームで動くプログラムを作ることができます。<!--画面出力を扱うためには近年の[[w:ビデオカード|ビデオカード]]の発展についても見る必要があります。しかし、ビデオカードの機能は2次元の描画に関してはあまりあらわには見えないので、この話題は3次元の描画を行うときに再び戻ってきます。-->
*[[ゲームプログラミング/ブロック崩し]]
*[[ゲームプログラミング/画面出力]]
==目次==
=== ジャンル別のプログラミング手法 ===
==== 3Dグラフィック ====
* [[ゲームプログラミング/3Dグラフィック]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
==== RPG ====
* [[ゲームプログラミング/RPG]]
==== アクション ====
※未作成
==== パズル ====
※未作成
==== シミュレーション ====
※未作成
=== ゲームのデバッグ ===
* [[ゲームプログラミング/デバッグ]]
=== 入力 ===
OSの種類によって、キーボード入力やマウス入力の受け付けのさいのプログラムの書き方は違う。
Windows API での具体的な手順は『[[ゲームプログラミング/入力]]』で説明する。
=== ゲームエンジン ※未完成 ===
* [[ゲームプログラミング/Unity]] ※リンク先ページの編集者が現状ではUnityの著作・調査を放棄中なので、調べ物としては役立ちません(2021年12月19日に本文を記述)。
=== 非プログラミングのゲーム製作の関連作業 ===
==== バランス調整 ====
*[[ゲームプログラミング/バランス調整]]
厳密にはプログラミングの話題ではないが、ゲーム製作では必要な知識なので、サブページで説明する。
:※ゲームデザインに関する記述をここに集積し分離したい、という編集者の意図もある。
==== ゲーム用の書類の書き方 ====
説明書や仕様書(しようしょ)の書き方については、『[[ゲームプログラミング/書類]]』で解説する。
== 未分類 ==
===Visual C++プログラムによる文字画像の出力===
Visual Studio付属のフォームデザイナ(VSの用意するGUI自動作成ソフト)によるGUIオブジェクト作成では、RPG用には使いづらい。いや、ひょっとしたら上手に使う方法はあるのかもしれないが、様々な理由で難易度は高い。
そこでまず、Visual C++で、フォームデザイナをなるべく使わずに文字や映像を出力する方法を考える。
選択肢は、幾つかある。
1.フォームデザイナを1つも使わない方式
*Windows APIで入力していく方法。(Wikibooksに『[[Windows API]]』の入門書があります。)
*DirectXで入力していく方法。DirectX自体はWindowsAPIを利用している。
2.1つだけフォームデザイナのパネルを使う方式
*フォームデザイナで「パネル」という画像表示機能のコンポーネントを一つ用意して、そのパネルで表示する画像をゲーム内のストーリーなどに応じて切り替えるだけで、すべての画像表示を行う。
フリーソフトでゲーム用ライブラリの『HSP』はWindows API を呼び出す仕組みになっています(HSP関連のサイトを見ると、Win APIプログラミングの解説をしている場合もある)。
フリーソフトでゲーム用ライブラリの『DXライブラリ』は Direct X を呼び出す仕組みになっています。そして、ゲーム開発ツールのひとつであるウディタのソースコードは、DXライブラリとVisual C++ を使って書かれていると、作者が公表しています(ただしソースコードは非公開)。しかし、ウディタを用いたRPGプログラミングでは DXライブラリによるコーディングはしない。ウディタにはコード入力の機能は無く、マウス操作や、キーボード操作、キャラ名称や会話文などのテキスト文字や数値の入力のみに対応している。
===乱数===
そもそも乱数とは何かという問題があるが、それは高度な数学的な議論になるだろうから、我々はその問題には深入りできない。
ゲームにおける乱数的な処理では、事実上ランダムな値にならず、演出や調整のためにアルゴリズムが介入している場合も多い。例えばゲーム中のくじで「外れ」続くと、当たり確率が変動し、次からは当たりやすくなるアルゴリズムなども良く使われる。<ref>『ゲームプランナー集中講座』、P232</ref>。
ゲームは娯楽であり、実用目的のシミュレータではないし、アルゴリズム介入で、確率的にもいんちきが多いので、あまり厳密なランダム性が問題になることは少ないだろう<ref>『ゲームプランナー集中講座』、P231</ref>。
例えばさいころというのは典型的な乱数器だし、ゲームにもよく使う物だろう。
無印C言語には標準的乱数関数 rand()があるが、これを乱数発生に使うことに批判的な意見もあるし、機能もやや不足していると見れる。
Windows64bit では int rand(void) の出力は 32bit 整数だろう。まず stand関数で初期化してから rand()を呼ぶごとに疑似乱数が帰ってくる。これの複数回の連なりが乱数列だね。帰ってくる値は0 以上 定数RAND_MAX の値以下。
例えばさいころの数値が欲しいなら、rand の返り値を6で割った後、余りに1足せば、とりあえずそれらしいものはできる。
RAND_MAXは rand()の属性として定数が与えられているだけだから(Windowsで0x7FFF)、この値の変更はできない。
まあこれでもそこそこいい加減な乱数として機能するだろうが、最近ではもう少し改良された、質の高い乱数関数もある。
また、改良された乱数関数は、乱数の範囲も指定できるから何かと使い勝手が良いし、バグを防ぐ効果もあるのだろう。
<syntaxhighlight lang="cpp">
Random^ saikoro1=gcnew Random();// Random^ でRandomクラスの変数を作っている。gcnewはインスタンスをつくるための演算子。
int detame; detame=saikoro1->Next(1, 7);// Next メソッドで「〇〇以上△△未満」の乱数を指定できる。「->」はメンバーアクセス演算子。
MessageBox::Show("目"+detame.ToString()+"が出ました。");
</syntaxhighlight>
↑例えば上述のコードは前編集者が示したものだが、これは .NETプログラミングですね。.NET のSystem::Randomクラスを使っている。.NETのクラスは普通、C#かVisual Basic で利用するので、Visual C++で使えるようにするには結構面倒な手管がいるが、その辺は読者諸兄、ヘルプやネット情報を参照して、適宜辿り付いてほしい。
C++ の場合はむしろ、 #include <random> を宣言してそこで使える関数を使用するほうが簡単でしょうね。この場合でも、乱数としての精度も高いし、帰り値の範囲指定もできる。
===画像のちらつき===
画像がひんぱんに変化するアプリでは、画面が、ちらつく事がある。画面のちらつきは、ゲームのように、画像を凝視するアプリでは、かなり利便性を損なう。
キャラクターが1歩移動するだけで、画面全体がちらついたりする場合もあり、かなり、プレイヤーの不満になる。
これは、ダブルバッファ(「裏画面」と、良く言われる)という技術で、解決を図る。
Direct Xの用語では「スワップ チェーン」と呼んでいる。
.NET Framework開発環境の C++や C#でもダブルバッファの機能があると解説されている。いくつかのGUIオブジェクトのプロパティで、ダブルバッファの設定項目がある。
しかし前編集者が実験したところ、この機能を有効に使って確認することはできなかったとの指摘がある。ひょっとしたら何らかのマイクロソフトの解説に間違いがあって、工夫次第では利用できるかもしれないが、少なくとも今現在のこのページでは、その問題に関するリファレンスは提供できない。
そこでやはり、以前の項目と同様、Win32 API または DirextX の利用をこのページでは考えたい。
前編集者は、.NET Framework のフォームデザイナでは、ちらつき自体は解決できそうだが、グローバル変数の共有が困難だったり、アプリ内から終了コマンドが使えない、などの難点があると指摘している。
ただ現編集者はこの2点に関しては、解決策はあると思うが、しかし特に調査はしない。
前編集者は、.NETプログラムでゲームを作る難点をいくつも上げているが、おそらくどれも、.NET の仕様や全貌に精通すれば解決できるように思えるが、そもそもその全貌がかなり広大なので、解決の道のりは長いだろう。
そこで少なくともこのページでのWindowsゲームプログラミングは、Win32 API を利用したものになるだろう。
==セーブ、ロード、データベース==
===セーブ機能とロード機能の作り方===
ゲームでもシリアライズ機能が必要なことは多いだろう。数値(HPなどの各種パラメータ現在値)や文字列(例えば、プレイヤーの作成したキャラクターの名前)や現在地やフラグ状況などなど、セーブの機能は欲しい。一番簡単な方法は、C言語の fopen 関数のテキストファイル書き込み機能で、テキストファイルとしてセーブすることだろう。
Windows API には CreateFile関数 があるが、テキストファイルでの素朴なセーブは一番簡単で単純なセーブ法だろう。そしてテキストファイルを読み込んでプログラムに各種変数を配置して、ロードとする。
書き込みとしては、一番単純なC言語記法では、fprintf ですかね。C++としての書き込みをしてもいいし、読み込むのも、一番基本的な方法で。基本Cだとしたら fscanf で、この関数でテキストの数値も変数として読み込めるはずですよ。場合によっては atoi関数 で文字列→数値の変換をすることもありますかね。
基本的にデータファイルは、OS もアプリケーションも、テキストファイルとバイナリファイルの2分類で考えるでしょう。でもテキストファイルだってバイナリの集まりなんですが、テキストを扱うファイルだけ特別視していると考えていい。
そして多少それらしいデータを作りたいときは、バイナリファイルで作るという事になるでしょう。
バイナリファイルでもデータとしてのファイルと、OS が機械語または何らかの仮想的な機械語として扱う実行ファイルがある。それらのバイナリは種類に応じて多くは冒頭にファイル識別子の情報があるだろうし、OS や アプリケーション側で工夫を凝らして、特定の条件を満たす場合しか動作しないようにしているだろう。そしてバイナリファイルを扱うときは、セキュリティの安全性も考慮するだろう。
基本的にプログラム側は何でもありだが、識別子の判別その他、ある程度様々な考慮をしないと、困った事態が起こり、プログラマーが責任を問われることも起こるかもしれない。
まあその時はいつものように口先だけで謝り、それでも許してくれなかったら、腹をかっ割いて死んでお詫びすれば、世間の人たちは美事な武士道精神と言って、口々に褒め称えてくれるだろう^^。←もちろんこれは冗談^^;;;。
市販のパソコン用ゲームや同人ゲームでは、テキストファイルではなくバイナリでデータ保存するゲームの方が圧倒的に多いだろう。その方がそれらしいしかっこがつく。ゲーム開発ツール側自体も、そうなっている場合が多い。RPGツクールもウディタも、セーブデータの形式はバイナリ。
テキストデータは基本エディタで開けるが、バイナリデータも内容によっては結構ぐちゃぐちゃの状態で開ける。バイナリデータはバイナリエディタで開ける。バイナリエディタのリードオンリーモードやバイナリビューアみたいなものがあれば、データーを壊さないで結構安全にデータ調査できる。
データ内容を秘匿したければ、バイナリ化だけではなく、暗号化も必要になるかもしれない。
===機能の整備===
セーブ&ロード機能の実装時には、まずセーブ機能から作るのがやりやすいという。
しかし最終的には関係関数の整備は、ロード機能が基盤となるだろう。
データや変数を、一定のスタイルでセーブして、一方で正しいスタイルでロードする、この機能が必要なわけですよね。
シリアライズされたデータを、型を決めたうえで配置しなければいけないから、ロードのプログラムの方が複雑に、面倒になる。
結局データのシリアライズは、ロード機能が基盤となり、その機能の作りやすさが、セーブ機能の作りやすさも支配するようだ。
== ゲーム中の特殊イベント ==
* [[ゲームプログラミング/特殊イベント]]
たとえばRPGなどでは、ゲーム中で1回しかおきない特殊なイベントとかを作りたい場合があるでしょう。RPG以外でも、シミュレーションゲームなどで特殊イベントを実装したいこともあります。たとえば、もし日本の中世の戦国時代シミュレーションゲームで「桶狭間の戦い」が3回も起きたりしたら困ります。
そういう話題について、とりあえずの叩き台的な、「こうプログラミングしたら、いいんじゃない?」的なことをリンク先では説明しています。
== スケジュール管理の教養 ==
[[File:Tokai Hairo.jpg|thumb|500px|ガントチャートの例:東海発電所の廃止解体工程]]
個人でのゲーム開発には全くの不要な知識ですが、スケジュール管理表といわれる技法がいくつかあります。
「作業責任分担表」(TRM: Task Responcibility Matrix)といわれるスケジュール表から、
それをグラフ的に図示したガントチャートといわれる表を作って、その表を見て作業計画を判断する方法です
<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
{| class="wikitable" style="float:left"
| 仕事
| 担当
| 状態
| 開始
| 終了予定
| 終了日
|-
| 仕事1
| 田中
| 済
| 2021/10/03
| 2021/10/10
| 2021/10/10
|-
| 仕事2
| 田中
| 仕掛
| 2021/10/11
| 2021/10/13
|
|-
| 仕事3
| 鈴木
| 済
| 2021/10/05
| 2021/10/08
| 2021/10/08
|-
| 仕事4
| 山田
| 未着手
| 2021/10/13
| 2021/10/17
|
|-
|}
{{-}}
ガントチャートでは普通、横軸に日程をとります。
ゲーム業界でもガントチャートの横軸は日程です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
ガントチャートとして図示することで、どこがボトルネックなどのリスク要因になりやすいのかが、一目瞭然です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
なので、それを見越して、スケジュール管理をします。
このTRMとガントチャートは、IT業界だけでなく建築工事でも使われるので、
社会人の知識のひとつとして知っておくと良いです。
ガントチャートによるボトルネックの洗い出しも、建築学の教科書でも良く教わる内容です。
よく住宅リフォーム工事などで、一般人でも建築業者の提示するガントチャートを見る機会があります。
新人の段階でそんなの書く機会はないかもしれませんが、しかし知っておくと上司からの命令が理解しやすいので、
知っておくと得でしょう。
== ストーリー作成などの順序 ==
ストーリー作りに限らず、ゲーム作りではゲーム全体を先に作るのが先決です。ニュアンスは違いますがアトラス社いわく(ゲーム開発では)、おおむね「ゲーム全体に全体に血を回すのが先」といった内容の格言があります<ref>[https://news.denfaminicogamer.jp/projectbook/191030a/2 『【ゲームの企画書】『ペルソナ3』を築き上げたのは反骨心とリスペクトだった。赤い企画書のもとに集った“愚連隊”がシリーズを生まれ変わらせるまで【橋野桂インタビュー】』2019年10月30日 11:30] 2020年12月1日に閲覧して確認.</ref>。
プレイヤーが見たいのは、ゲーム全体のストーリーやテンポといったゲームの全体像です。細部は、あくまで補助的であり、そういった細部に対するプレイヤーの興味も、あくまでオマケの範囲でしかないのです。
さて、暗黙の前提として、ゲームのストーリーは、システムと連携・調和したものでなければなりません。
このため、ゲーム作家によっては、先にシステムを決めてから、あとからストーリーを作るような方法論を採用しているクリエイターもいます<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.306</ref>。
さて、ともかくゲームのストーリー作成は、なんらかの方法で、全体像を先にきめてから、あとから細部を作っていきます。
これを実現するための方法として、いくつかの方法があります。
ドラマの脚本などで使われる、「ハコ書き」という方法を使う人もいます。全体像に当たる「大ハコ」を記述してから、「大ハコ」→「中ハコ」→「小ハコ」と記述していく方法です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.184</ref>。
そのほか、別の方法としては
:* エンディングを大まかに先に作る
:* 機能の実験を簡易でいいので事前にしておく(※プロトタイプの項目を参照)
:* 使用頻度の高い部分から作る
のような方法もあるでしょう。
そのほか、書籍『ゲームプランナー入門』で紹介されている事例だと、アルファ版(α版)を中盤から作り始めています<ref>吉冨賢介『ゲームプランナー入門』、P17</ref>。α版の製作目的の一つとして、そのゲームが本当に面白いかの検証や(駄目すぎたら製作中止)、改善するとしたらどこかの洗い出しが目的ですが、中盤だとそのゲームの全体像がわかりやすいので検証しやすいからのようです。
作品やジャンルや製作目的などによって、エンディングからか中盤からか、どこから作り始めるかは若干の違いはあるでしょうが、ともかく必ずしも冒頭部から作り始める必要がないということです。
;エンディングおよびラスボス戦闘を早めに作る場合
まず、ゲーム用のストーリー(ゲームシナリオ)の作り方ですが、学校などでの作文の書き方の順序と、ゲームシナリオの書き方の順序は、違います。
作家にもよりますが、ゲームシナリオを作る場合、エンディングを早い時期に作る人もいます<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
文献『ゲームプランとデザインの教科書』によると、シナリオでなくシステム面についても、先にゲーム全体のクリア条件を決めてから、あとから各ステージなどのクリア条件を決めていくことが多いようです<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.253</ref>。
では、シナリオの仮のエンディングについて考えていきましょう。このエンディングは、当面の仮のエンディングなので、あまり作りこむ必要がありませんが、しかしエンディングが必要です。
エンディングのシナリオと、キャラクターの性格づけの設定があることにより、そのゲームで何を主人公に目指させるべきなのかが、作者にハッキリとします<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
ともかく、方法は作家ごとに色々と違いはありますが、そのゲームの全体像を何らかの方法で決めるのが先です。
また、ゲームでは最後のラスボス戦がそのゲーム中でもっとも高負荷だったり、全部のシステムが組み合わさってたりしますので、先にエンディングを作っておくことで、そのゲームで最大負荷の状態を検証する事が出来ます<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
また、3Dゲームでは、RPGなら戦闘シーン、アクションゲームならアクションシーンが、一般的に、最も高負荷です<ref>ntny著『ローポリスーパーテクニック』、ソフトバンククリエイティブ、2010年2月16日 初版 第5刷、P28</ref>。
処理オチの確認とかも、この方法で確認できます。
また、ラスボス戦およびエンディングは、そのゲームの大きな見所のひとつであり、ほぼ最大の見所がラスボス戦およびその前後です。
いっぽう、中盤などは、比較的に重要性が下がります。
なので、スケジュール遅延や容量不足などで、ストーリーを短くしないといけなくなった時などは、ラスボス戦以外の場所を削ることになります<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
よって、ラスボス戦などは削る可能性が少ないので、先にラスボス戦を作っておけば、たとえスケジュール遅延などをしても、先に見所を作ってあるので、早くリリースしやすくなります。
{{コラム|イラストなど異分野での類似事例|
似たような、先に結末を決める事例は、イラスト技法にも存在します。
1995年ごろ、イラスト雑誌『コミッカーズ』(1995年 コミッカーズ季刊 夏号)に、当時の人気漫画家&イラストレーターの藤島康介がインタビューされたのですが(なお、その号の表紙は別の漫画家(唯 登詩樹))、
藤島はインタビューにて、おおむね内容『よく若い漫画家さんから相談で「先生みたいに女性の長い髪を書くとき、毛先を書くのが難しいです。根元は書けるのに」との相談を受けるのですが、
僕(藤島)は髪を描くときは毛先から始めて根元に向かって描いてます』みたいなインタビュー返事をしました。
こういうふうに、大切なのは頭の使いようです。要するに、ズレるのが怖い場所は、先に位置決めをすればいいのです。髪の房(フサ)の根元と毛先だったら、ごく一部の場所を除いて、読者の目線では毛先のほうが目立ちます。
だったら、作画の際の誤差は、読者には気づかれない根元の部分に押し付ければいいのです。
よくよく考えれば、イラストに限らず機械製図とかでも普通にそういう位置決めの優先指示の記法はあるのですが、
しかし世間の人は、なかなかそういう発想を異分野に応用できません。普通の人はついつい、実際の髪の伸びる順序どおりに根元から描いてしまいます。
}}
* 目標の提示
ゲーム中の目標の明確化は、シナリオの設計手法としてだけではなく、たとえば各ステージ目標の提示などは、プレイヤーをゲームに引きこむ手法にもなります。
というか、文献『ゲームプランナー入門』によると、もしゲームの目標や課題が満足に語られていないと、プレイヤーは最悪、「?」となり、コントローラーを置いてゲームを中断してしまいます。なので、設計の際、各ステージやエリアなどの冒頭で、そのステージの課題や目標などを明示する必要があります<ref>『ゲームプランナー入門』、P39</ref>。
ファミコンの古いアクションゲームだとゲーム本編では目標は語られていませんが、しかし説明書などではキチンと目標が語られており、実際にスーパーマリオブラザーズの第1作目では説明書では目標がクッパを倒してピーチ姫を救出することだと語られています<ref>『ゲームプランナー入門』、P54</ref>。
=== その他の開発順序 ===
==== チュートリアルの細部は後回し ====
:※ 特に出典は無いですが、技術系の仕事では常識的な考え方です。
RPGやシミュレーションゲームなど、プレイヤー視点では、ゲームの始めのほうに操作説明などのチュートリアルのイベントがありますが、しかし、実はチュートリアルの細部は、作るのが後回しになる場合が多々あるかと思われます。
なぜなら、ゲームで仕様を変更するたび、チュートリアルも変更の必要が生じるからです。このため、チュートリアルのとりあえずの完成の時期は、けっこう後回しになります。
よほど仕様の単純なゲームなら別ですが、そうでない場合、あまり開発初期からチュートリアルの細部を作りこみすぎないようにするほうが安全でしょう。
そもそも、チュートリアルをゲーム本編に組み込み必要もありません。たとえば説明書などで、細かい説明を代用する事だって可能なわけです。
チュートリアル部分に深刻なバグが発生してないかとか、逆に本編ゲーム中にチュートリアルが異常起動しないかなどの確認のために、開発初期からチュートリアルを組み込んでも構いません。ですが、おそらく、最終的なチュートリアルの完成時期は、仕様やゲーム全体像が本当に完成・確定したあとの時期なので、ゲーム本編の完成間近の時期になるか、もしくは本編完成後になるでしょう。
== 古典ゲームと技術限界 ==
ゲームを作る際、過去の名作ゲームを参考にしようと思うでしょうが、
しかし過去のゲームの設計は、当時の性能の限界に影響を受けているので、
果たして現代のコンピュータ性能の飛躍的に上昇した時代でも過去の設計をそのまま参考すべきかは、
やや検討の余地があるでしょう。
歌舞伎などの古典技芸の伝承の格言で『師を見るな、 師が見ているものを見よ』という教訓があると言われています。
このセクションでは、主に1980年代のファミコン時代のゲームを例に説明します。
=== スプライト ===
ファミコン時代の昔のゲーム機には、一画面に表示できるキャラチップ数(敵チップも含める)に上限がありました。
一画面中に表示できる限界は、だいたい、マリオが一画面中に数十人ぶんです。(実際の数値については、本ページでは触れない。説明の本質には関係ないので。)
ファミコンでは、このような仕組みを 「スプライト」と呼んでいました。(実はマリオ1体の表示の時点で既に、いくつかのスプライトの小単位を合成したものになっているのですが、説明やややこしくなるので、このページでは触れません。)
ともかく、実は昔のゲームのステージ設計は、スプライトの制限を前提にしたものになっています。
極端なハナシ、もしたとえばシュテイングゲームなどで、動く敵100体をボムで一瞬で倒せるようにしたゲームを設計しようとかファミコン時代に思っても、
ファミコンではすでに敵100体の表示の時点でグラフィック性能的に原理的に無理なのです。
どうしても敵100体を表示したい場合、表示のタイミングを変えます。
たとえば、
:1タイミング目では0~10体目までのAグループを表示、
:2タイミング目では11~20体目までのBグループを表示、
みたいにして、タイミングを変えることで、なんとか表示するのです。
このため、画面上に動くキャラクターが多いと、一瞬、ほかのキャラが消えるのは、裏側でこういうタイミング切り替えの処理が行われているからです。
説明の都合上、本ページではキリのいい「10体目」までと 上記の例では表現しましたが、実はファミコンの制限はもっときびしく、横1列上には8体目までしか表示できないと言われています。(しかもマリオ1体自体が、じつは2体×2体の計4体チップを使っているといわれる。なのでマリオ5体は同一ライン上には表示できない。)
なおシューテイングゲームの場合、敵チップだけでなく、敵味方の双方の弾丸もチップを利用しますので、実際の制限は上記の数値例よりも、もっと厳しいでしょう。
また、プレイヤー視点ではキャラクター1人にしか見えていなくても、背の高いキャラクターなどはキャラクター2体以上に相当するなど、注意しなければならないこともあります。
だからファミコン時代のアクションゲームで、巨大ボスのいるステージでは、ボス以外の敵が出現しないのは、おそらくですが、プレイヤー視点では1体のボスに見えても、内部プログラム的には敵チップを何体ぶんも利用しているのでしょう。
しかも巨大ボスは、ゆっくりとしか動きません。
おそらく、そのゆっくりとした時間内にVRAMを書き換え中だったのでしょう。
日本ではコトワザで「ウドの大木」みたいな言葉があるので、なんとなく巨大ボスがゆっくりと動いても不自然ではないかもしれませんが、よくよく考えたら現実世界の大男はけっこう動きが早いです。(レスラーやヘビー級ボクサーなどを考えれば分かるでしょう。)
=== 書き換え速度と背景グラ ===
ファミコンのマリオでは、書き換えの手間を省くために、一説には、たとえばマリオ1の地上ステージの世界の空の青色は、実はほとんどの場合、マリオが横スクロールしても空の青色の部分は書き換えをしておらず、横スクロールする前の青色をそのまま使いまわしていると言われています。
なぜそれで効率化できるかというと、ステージ中の障害物はほとんどのステージの場合で、画面の比較的に低い位置に障害物があるので、その低地の障害物だけを書き換えすれば済むからです。
だからファミコン時代では、こういう理由から、ステージの背景グラフィックや、障害物配置なども決まっているでしょう。
だから果たして、現代でもそれを過去の名作のステージ構成を踏襲すべきかどうかは、分かりません。もちろん、仕組みを分かった上で真似るのなら、それは特に問題ないでしょう。
=== アナログテレビの にじみ ===
ブラウン管では、細かすぎるドットは表示が、にじみます。ゲームに限らず、テレビアニメや一般の実写番組などでも同様、にじみます。(どのように、にじむかは、専門的なので説明を省略する)
だから、ファミコン時代から、だいたいプレステ1時代のゲームのグラフィッカーは、このことまで意識してドットを描いているはずです。
ともかく、液晶テレビとブラウン管テレビでは、同じ画像データでも表示結果が変わります。
レトロゲームから勉強する際は、ファミコン〜プレステ1時代のレトロゲームでは、データ上の解像度よりも実際のディスプレイ上の映像は細かいことに気をつける必要があります。
たとえば滲み(にじみ)を意図的に利用することでテレビの解像度以上の表現をしていたりしていました。
また、ファミコンのドットは縦横の長さが縦方向と横方向とで長さが違うので、そこまで考慮して、グラフィッカーは絵を描いています。
また、ドットの図形的な細かさだけでなく、色についても、にじみによって、当時のゲーム機の色用のビット数の限界を超えた表示をファミコン時代から行っていました。
つまり、同じドットの黄色の単色でも、そのドットの幅が1ドットか2ドットかで、テレビ上で表示される色が違います。「色が違って見える気がする」ではなく、実際にブラウン管のディスプレイ上では色が違うのです。言い方を変えると、ブラウン管テレビでは元の画像データ通りには色は表示されていません。(さらに縦方向と横方向とで色のにじみ方が違うが、専門的すぎるので、説明は省略する。wiki書くために調べるほうも大変なので。)
なので、もし現代の人がファミコン当時のゲーム作品のグラフィックを参考にする際は、このことに気をつける必要があります。一番、手軽なのは、そもそもグラフィックの細部については参考にしないことです。
これはつまり、もし公式エミュレーターなどでファミコン時代の古いゲームを、現代の液晶ディスプレイ用のゲーム機でプレイしても、エミュレーター側で過去テレビのグラフィック特性の再現のための特別な工夫をしてないかぎりは、実はグラフィックの表示結果が当時のものとは異なるわけです。
一方、パソコン市場では、ノートパソコンの普及し始めた1999年頃には液晶ディスプレイのものが比較的に安価で出て来たので、この頃からパソコンゲーム市場では次第にブラウン管のにじみを考える必要が無くなったでしょう。
なお、アナログテレビはそもそもテレビ自体の解像度が低いので、プレステ2時代あたりからのゲームには合いません。だから、プレステ2時代あたりからは、あまりブラウン管の特性を考える必要はなくなります。
逆に言うと、あまり指摘されないことですが、プレステ2時代の当時の人が当時の最新ゲーム機をプレイするには、もし既存のアナログテレビを使い続けていた家庭は、テレビ受像機そのものを買い換える必要があったという亊です。
一応、家電量販店などでテレビ用のアナログ/デジタル信号の変換機などを購入してテレビに接続するなどして使えば、デジタルテレビ用のゲーム機もプレイ可能ですが。
だからアナログ放送自体は2010年くらいまで続いたとはいっても、あまり当時のゲーム機をアナログ用テレビでプレイしていたとは考えにくくはあります(プレイヤーの好みによる)。
アナログ停波以降の時代である2010年以降の現代では、もうテレビ番組の受像でもブラウン管は一切用いられていないので、もはや現代のコンテンツ制作では特に考える必要はありません。
ブラウン管自体のドットの縦横が違っている。
このため、ブラウン管を前提にしたゲーム機やパソコンはそれに対応するために画像データ側のドットの縦横比が違っている。
ゲーム機やパソコンの種類、さらにはアーケードゲームの基盤といったハードウェアの種類ごとに、コンピュータ側でのドットの縦横比の管理は違っている(らしい)。このため、移植のたびに、ドットは書き直しになったようだ。
古いゲームの制作では「ドット用紙」という方眼紙のような印刷書面がある(らしい)のだが、そのドット用紙の時点で1マスの縦横比が少しだけ違い、1マスが長方形である。1ドットだけでは長方形であるのに気付かないかもしれないが、しかし「ちりも積れば山になる」ように、何十や百ドットも積み重なれば、縦横の長さは大きく違ってくる。
現在のパソコン用のドットエディタ(という画像制作ツールがある)は1ドットが正方形であるが、しかしファミコン時代は1ドットが(ドット用紙の時点で)少しだけ長方形である。(なお、画像制作ツールそのものの作り方については、『[[ゲームプログラミング/画像ファイルの作成プログラム]]』で説明する。ゲーム制作では普通は必要ないが、知識として。)
ファミコンの色数制限は52色から4色×4パレット(1パレットあたり4色)を使えると言われている<ref>[https://mynavi-creator.jp/blog/article/history-of-2dcg-designer
『2DCGデザイナーなら知っておきたい2DCGゲームの歴史』 2017/8/21 マイナビクリエイター編集部 ] 2021年12月30日に確認. </ref>。しかし実際には、4色のうち1色は透明色として利用される色であり、全パレット共通の色である(なので3×4=12色になることのいなる)。スプライトのパレットとは別に背景のパレットがあるので実際には、もっと16色以上の多くの色数が一画面内で使えるが、しかしその他のさまざまな制限があるので、合計で一画面内で25色が使えると言われる(12 × 2+1 = 25)。
しかし実際には、ブラウン管の滲み(にじみ)を利用しているので、当時のプレイヤーには1パレットだけで描かれた1キャラのキャラチップ内でも3色以上の多くの色が見えているだろうし、画面全体でも25色内にない色がプレイヤーの目には映っていることになるし、もしかしたら52色にない色がプレイヤーには見えているかもしれない。なお、スーパーファミコンの色数制限は32,768色から16色8パレットであると言われている。
レトロなゲーム機では、さらにメモリ容量やストレージ容量などの制限もあり、けっして仕様上の最大色数を気軽に利用できたわけではないだろう。こういう制限もあったからか、ネットではファミコンの色数が「4色」やら「8色」、スーパーファミコンの色数が「16色」や「256色」などとも言われることもある。
{{コラム|「ドット絵」とは|
よく世間には、ファミコン時代のゲームの、ゲーム中での絵柄のことを「ドット絵」という人がいます。プレステ1やセガサターンのポリゴンによって、「ドット絵」が無くなったと思っている人もいます。
しかし現実には、プレステ以降でも、顔ウィンドウの顔グラフィクや、キャラチップなどのグラフィックでは、その制作時にドット単位のグラフィック指定は行われています。
たとえば装備品で武器の横に小さい剣の絵などのアイコン画像が書かれている作品などもありますが、こういったアイコン画像もドット単位の指定で描くでしょう。
こう指摘すると、「プレステ1以降のゲームは解像度が高い」とかよくわからない反論をする人がいますが、しかし「ドット」という工学用語のどこにも、「解像度が低い」とかの意味はありません。また、「ドット」というのをブラウン管ディスプレイの映像だと思ってる人もいます。
しかし、液晶ノートパソコンの普及した2001年以降の液晶モニターの時代ですら、
「液晶のドット欠け」などのように「ドット」という用語は使われます。
「ドット」というのは、けっしてゲーム用語ではなく、「液晶のドット欠け」のように電子工学などですでに意味が決まっているので、ゲームオタクの戯言(ざれごと)は「ドット」の意味には無関係です。
さて、プレステ1以降のゲームでもキャラチップなどでは、ドット単位の指定が行われるのでした。
それどころか、携帯ゲームソフトでは、ガラケーの時代から既にドット単位の指定は現役の手法であり、スマホゲーム時代の現代でも現役です。
だから「ドット絵には魅力がある」とかいって、ファミコン時代のゲームばかりあげる人は、こういう現役のドット絵作家の努力が目に入らない人ですので、なるべく信用しないほうが良いと思います。
また、画像編集のフリーソフトまたはシェアウェアで、現代でも「ドット エディタ」と呼ばれる種類の画像制作ソフトがあり、少なくとも2D同人ゲームの制作ではよく使われます。
ツクールやウディタのドット絵を作る場合でも、ドットエディタを使って作るわけです。
ゲームに興味なさそうな人が「ドット絵」をレトロゲームの絵という意味で使うのは仕方ないかもしれませんが、しかしゲーム通みたいな顔して「俺ってけっこうオタクなんだぜ」みたいなフリしてるのに、レトロ的な用法で「ドット」という言葉を使う人はアレです。
おそらく、本当はけっしてドット絵が好きなんじゃなくって、単に自分の子供時代の思い出が好きなだけだと思います。
ニュアンスは違いますが、アニメ評論でもそういう話があります。1990年代後半に岡田斗司夫と誰かの対談で(おそらく書籍『マジメな話』での対談)、
「アニメの黄金期はいつか?」というよくあるアニメオタク談義について、
対談相手が言うには、
よく「70年代だ」「いや80年代だ」とかで議論が始まるが「いや12歳だ」というオチが有名だと。
}}
=== アナログテレビの焼きつきなど ===
あまりゲーム評論では指摘されないのですが、
このほか、ファミコン時代はテレビ受像機がアナログのブラウン管ディスプレイなので、
あまり長時間、同じ色をディスプレイ上の同じ位置に表示し付けていると焼きつきが起きる可能性があるので、
ステージごとにコンセプトになる背景色を変えたり、
あるいはステージの背景色を黒にしたステージを増やしたりとかの工夫も、必要だったかもしれません。
ゲームではないですがパソコンソフトなどの古いソフトは、こういったディスプレイの焼きつきの事を考えており、だからスクリーンセーバー機能の搭載など何らかの対策をしています。
ともかく、あまり、特定の色ばかり続けて使いすぎないようにする工夫が必要だったでしょう。
アナログテレビは西暦2010年のアナログ停波する時代まで使われていたので、焼きつき問題はファミコン以降のプレステ1~2時代のゲームにも関係するでしょう。
ネット上にはデマで「ブラウン管だと焼きつきが起きない」(×)というデマがあるが、しかし西暦2001年くらいの筐体パソコンのモニターはまだブラウン管が多かったし、その時代からすでに焼きつき防止のためにスクリーンセーバーがWindowsに搭載されていた。だからデマ「ブラウン管だと焼きつきが起きない」(×)にダマされないように。
なお、現代のテレビ受像機には、焼きつき防止のためにすでに「ピクセルシフト」という機能があって、
これは画面上の映像の表示位置をタイミングによって微妙にズラす機能です。こういう機能がすでに搭載されているので、わざわざゲームソフト側で実装する必要はない。そもそも液晶モニターは、焼きつきが起きにくい。ただし有機ELはどうだか、まだ新しい技術なので分からない。
== 脚注 ==
<references />
== 関連項目 ==
* [[ゲームプログラミング/コンピュータゲームの種類]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
* [[プログラミング]]
* [[w:ゲームプログミング]]
{{DEFAULTSORT:けえむふろくらみんく}}
[[Category:ゲーム]]
[[Category:情報技術]]
{{NDC|007.64}}
ad8d7k7u2lo8zpmu9txucw5mqxbc8f2
205838
205837
2022-07-25T11:50:42Z
Honooo
14373
/* ゲーム中の特殊イベント */
wikitext
text/x-wiki
<div class="pathnavbox">
* {{Pathnav|ゲーム}}
* {{Pathnav|工学|情報技術|プログラミング}}
</div>
== 概観 ==
このWiki参考書では、コンピュータを用いた[[w:ゲーム]]のプログラミングを扱います。つまり、いわゆる「テレビゲーム」や、[[w:コンピュータゲーム|コンピュータゲーム]]に関する記述についてです。
ここでは家庭用のパーソナルコンピュータで扱える範囲の事柄、それらのゲームソフトをつくるためのプログラミングについて議論します。必要に応じて家庭用ゲーム機の話題にも触れますが、あくまで派生的なものです。本書はプログラミングの教材であるので、大多数の読者が最初にプログラミングで触れるであろうパーソナルコンピュータでのプログラミングを、特にことわらないかぎりは想定しています。
用語に関して、コンピューターゲームの世界独自なものもあるでしょうから、適宜『[[ゲームプログラミング/コンピュータゲームの種類]]』などを参照してください。
== 本書の目的 ==
この教科書『ゲームプログラミング』の目的は、題名にもあるとおり、プログラミングによってゲームを作るための技術の参考資料を目的としています。
ゲームクリエイターやゲームデザイナー(絵描きではなくゲームの設計者のこと)のためではなく、プログラマーのための教科書です。
したがって本書では、ゲームとは関係の少ない一般IT企業での仕事のしかたについての記述もあれば、製造業系の組込ソフトなどに関する概要的な記述もあります。
なぜなら本書はゲームクリエイターではなく、たまたま何らかの理由でゲームを作っているプログラマーのための教科書だからです。たとえゲーム会社を退職しても、他の一般IT企業に転職してもプログラマーとして応用できることなども目指して本書は書かれています。
従って、紹介する話題が、かなりIT系、テクノロジー系の話題に片寄っています。本書で紹介するクリエイター論やデザイン論は、派生的なものにすぎません。
;本書を扱う上での注意点
特にことわりのないかぎり、本書ではC言語でのプログラミングによってゲームを作りたい読書を念頭に説明しています。
だから、ゲームの生産効率性を無視してでも、本来ならRPGツクールのような開発ツールを使ったほうが早いシンプルなゲームの場合ですら、本書ではC言語または他のプログラミング言語での開発にこだわった方法を説明している場合もあります。
;その他、本書について
このページとそのサブページだけを見ていると本書は「ゲームクリエイトの教科書かな?」と捉えられるかもしれませんが、
しかしこのページとは別に本wikibooksには「[[プログラミング]]」というページがあり、そこではC言語やJavaなど代表的なプログラム言語のwiki教科書にリンクしています。ゲーム限定の話題ではないですが、プログラミングのコードについても、そちら『[[C言語]]』や『[[Java]]』やなどの教科書のほうが(実際に動作するコードの量が)充実しています。また、Visual C++ での画面出力については『[[Windows API]]』に入門的な説明があります。
本書『ゲームプログラミング』はそういったプログラミング教科書一覧の一部でもあります。C言語やWindows API の教科書では、これをどうやってゲームのプログラミングに応用すればいいか説明できないので(本wiki『[[C言語]]』はけっしてゲーム目的のページではないので)、ゲームの実際としてプログラミングの話題を切り離すために本書『ゲームプログラミング』は存在しています。
なので本書にゲームデザイン論やクリエイター論などの内容の充実は期待できません。
本書『ゲームプログラミング』は現状、プログラマー目的以外には対応できないかもしれません。もしプログラマー目的以外の無料のwiki教科書が欲しい方は、現状では、自分で本wikiに加筆するか、あるいは本書『ゲームプログラミング』とは別に新規Wiki執筆を検討していただきたい。
== ゲームを作りたいな、よし、ゲームを作ろう。でも… ==
===しかし自分の本当の目的ってゲーム作り?===
「ゲームを作りたい」と思ったのなら、まずはあまり細かい難しいことは考えず、実際に作り始めてみるのが一番いいと思います。もちろんプログラミングについてほとんど何も知らないのなら、ある程度の勉強は必要ですが、ある程度の知識があるのなら、プログラミングの技量や知識の充実を気にするよりは、実際にゲームの完成を目指してプログラムを書いてみるのが一番いいようですよ。その過程でプログラミングの学習や経験は積んでいけますしね。JavaScriptやPython、無料でプログラミングに取り組める環境も、今現在では充実しています。
しかし、ゲームをプレイするのが好きだからと言って、ゲームを作る、までが本当に自分が好きかどうか、試しに少し作ってみたら、少し考えてみるといいですね。
例えば読者の中には、「私はRPGがすき」という人も多いでしょう。
RPG が好きという事はおそらく、よくRPGの題材になる西洋ファンタジーのストーリーや世界も好きという場合が多いでしょう。そして一方で現実のコンピューターRPGで魅力的に提供される、イラストや音楽が好きという場合もあります。
実際のゲーム業界の人々も、ゲームを彩るイラストレーションや音楽がいかに重要な要素かを語っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P85</ref>。
さて、ここで問題なのですが、「ゲームを作りたい」と貴方が思っていたとして、あなたが本当に作りたいのはゲームなのか?あるいは本当はイラストが描きたかったり、音楽を作りたいのではないか?
…というのは、ゲームというのは総合的な分野ですから、イラストや音楽はその要素として確実にありますが、それ以外、プログラミングやシナリオなど、様々な創作や創造が必要で、全ての作業量はかなり多いものになるでしょう。
そしてゲーム、コンピューターゲームにはゲーム独自の世界観があって、現実や小説や映画とは違う、独特の法則に支配された世界を作る必要があります。ある意味リアリティを持たない、リアリティから外れた世界です。だから、小説のようなリアリティにこだわるなら、ゲームは不向きかもしれません。
ゲーム作り始めの時点では、これらの判断は明確でなくても勉強目的でも構いませんが、しかその内「自分は本当にゲームを作りたいのか? Yes or no?」という疑問への答えが必要になるときがくるかもしれません。
試しにゲームを作ってみて、もし自分の本当の目的がゲームでないと分かったなら、それ以外の活動に移るのも、取る道の選択肢でしょう。
;給料は安い
職業として、商売としてゲームを作る場合、ゲームプログラマーの給料は洋の東西を問わず、安い事が知られており、書籍などでも言及されています。たとえば『CAREER SKILLS ソフトウェア開発者の完全キャリアガイド』(ジョン・ソンメズ 著)という欧米人のプログラマーの書いた本には、アメリカのゲーム業界ですらハードワークの割に賃金が低い事が記載されており、もし給料の高い仕事につきたいならウォールストリート(※米国の金融ウォール街のこと)のための仕事をするべきだと書籍中で指摘しています。
日本でも同様にゲーム業界の報酬が低いことは知られており、多くのゲーム会社の伝記漫画でも、よく語られています。
アニメーション業界と比べたら、ゲーム業界のほうが報酬が高いことは事実かもしれませんが、これは実は恐ろしいことに、アニメーション業界の報酬が異常に低いだけで、アニメーション業界よりはましだけど、結局は…というのが現状でしょう。
=== 同人ゲーム以外の発表の場 ===
2001年ごろの日本はネットを活用した同人ゲーム黎明期、フリーゲーム黎明期で、実験的な時代でもあり、多くのイラスト愛好、創作者や音楽創作者がゲーム制作に手を染めていたようです。この頃、まだイラスト投稿サイトや小説投稿サイトといったものは無かったか、あったとしても小規模でマイナーなものでした。
しかし2010年のあたりから各種の投稿サイトが普及したことにより状況は変わり、むしろ現在では、小説やイラストを発表したい人はそのジャンルの投稿サイトに直接アクセスしたほうが早く、そのためゲームを通して発表するのは人によっては廻り道かもしれません。
それをわかったうえで、それでもゲーム制作に身を投じるかを考えた上で、「よし、自分はゲーム制作をしよう」と思えるなら、ゲーム制作をするのが良いでしょう。
実際、今現在の作曲家やイラストレーターは、ゲームに関わったとしても、専門家として楽曲やイラストを提供するという立場に過ぎない場合もあり、自分自身が主体になってゲーム制作をする人は、プロアマ問わず少数派のように見えます。
同人ゲームの世界でも現在は(2021年頃に記述)、プログラマー系の作者が圧倒的に多い様です。
しかし、専門外の人だからこそ、メディアミックス的な意外な視点で新しいものが作れる可能性もあるかもしれません。コピーライター、作家の糸井重里が、マザー2の企画にたずさわった例もあります。しかし、あくまで「可能性」であり、成功はけっして保証されてはいないので、読者の自己責任でお願いします。
今現在のゲーム専門学校のカリキュラムはプログラミングが主体です。CGの授業は、週に2時間程の様。一方でゲームCG、或いは、一般CGに特化した学科もある様です。
あるWikibooks編集者Aは、もしイラストを描きたいなら、イラストの世界で描くのが安全、と考えています。ゲームプログラミングについては、プログラムを書ける人は絵コンテも描けそうだし、基本的にある程度の作図的なイラストを描ける人は多いだろうから、別にプログラミングに専念しろとは思っていません。
さて、読者がゲーム制作を職業として目指すのかどうかはともかく、とりあえず、ゲーム業界の状況を知っておくのが有用でしょう。
結局商業界の状況が権威をもってその分野を支配しているのがこの社会の基本なので、趣味でも職業でも、業界周辺のことを知っておくのは得ることが多いはずです。
文献『レベルデザイン徹底指南書』では、現実世界で自分が新しいスキルを1つ覚えたら、古いスキル1つはどれか忘れる必要があることを説いています<ref>大久保磨『レベルデザイン徹底指南書』、2016年12月14日 初版 第1刷発行、P81</ref>。著者は、最初はグラフィッカーでしたが、しかしプランナーに転職したので、グラフィック関係の技能は仕事では「忘れて」しまった、という内容を述べています。ただし、比喩的に「忘れる」とは言っていますが、実際には忘却し無くなってしまったわけではなく、仕事では時間の都合により両立できないので、グラフィック関係の技能は例え話で「忘れた」、のであり、現実にはグラフィッカー時代に培った観察眼をプランナー時代の現在でも活用している、と、書籍中では述べられています。
このことは職業、あるいは技能とは一般的にそういうもの、と考えることができるでしょう。
{{コラム|漫画家大塚志郎のアドバイス|
同人ゲーム界では、ゲーム制作と、イラストまたは作曲などを一人で兼ねている作者も、ある程度は居ます。一方ネットの世界には様々な簡単に利用できるフリー素材もあるので、イラスト作画や作曲をしなくてもゲーム制作は可能ですよね。
一人でイラスト作画や作曲をしながらゲーム制作をするのはある意味マルチタレントだとも言えますが、現実にその創作をしている人たちは、かなり年長のこの分野の熟練者が多いようです。若い19歳ぐらいの頃に、それらマルチジャンルを両立するのは、一般にかなり困難なことだと思われます。
漫画家の大塚志郎は、漫画家を漫画創作の手本にするならデビュー時代を手本にするのが良い、と、漫画家向けの技法の教育漫画で語っています。
大塚は、漫画家の人生のうちで、これからデビューを目指している新人に近い境遇にあるのは、ヒット後の漫画家の生活状況ではなく、まだ無名・マイナーな時代の態度・生活だ、と描いています。成功後の熟練した漫画家より、若いデビュー直後の作家をお手本にするのがいいだろう、という主張ですよね。
さて、それでもデビュー時代から複数ジャンルの同人活動を均等に兼業する意思が硬いなら、それはそれでひとつの考え方ですが、上述のリスクを知っておく必要があるでしょう。
}}
===ゲーム業界は産業のエンジン役?===
かつてはゲーム産業が、日本のIT産業やデジタル家電産業の中心的・牽引(けんいん)役であった時代がありました。しかし、2010年以降、この考えは当てはまらなくなっています。
PlayStation2あたりまでの時代は、経済評論誌の未来予想でも、「もしかしたら今後、家庭用の据え置きゲーム機がパソコンの代替品として、家庭のリビング家電の標準品になるかもしれない」という予想があった。ゲーム産業がそのような牽引役として、経済界から期待されていました。ソニーが国産CPUをプレステ2〜3に搭載したり、WindwosのマイクロソフトがXBOXでゲーム機に参入したり、そういう時代です。
しかし2020年代の今は違います。結局、2020年代のゲーム機に使われてる技術や部品は、パソコン用の部品や技術の流用、ゲーム機のCPUも、今やインテルなどのパソコン用CPUをゲーム機でも使っています。
もはや現代は、ゲーム業界は、産業のエンジンではないようです。
ですから今現在、新しい技術に興味ある人は、ゲームにこだわらず、直接的にその技術を勉強し改良したほうが近道です。
たとえば、インターネット技術を使って何か新しい事をしたいなら、ゲームを作るよりもwebアプリやサーバーwebサービスを作るべきだし、目的のネットワーク用ソフトウェアをそのまま制作したほうが早いし確実です。
古い経済知識の先入観にとらわれず、無理にゲーム制作にこだわらないほうが、自分自身の技能やキャリアも開けていくでしょう。
2010年に出版された商学書籍『メイド・イン・ジャパンは終わるのか』には、「しかしながら、ファミリーコンピュータで世界に攻勢をかけ、その後圧倒的な強さを誇っていた日本の家庭用ゲーム産業も、90年代末からはその競争力にかげりがみえはじめた。日本の国内市場は伸び悩み、成長率は鈍化傾向にある(図表7-3)。」とあります<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.263</ref>。
その「図表7-3」の統計値によると、
:ファミコン発売の1993年には2268億円、
:スーファミ発売の1990年には2430億円、
:プレステ1発売の1994年には3882億円、
:1995年には急成長して4769億円、
:1997年には4795億円で、ほぼこの頃がピークであり、
:2000年には3768億円にまで低下(プレステ2の発売年)、
:2005年には3151億円まで低下(XBOXの発売年)、
である。(青島らが『レジャー白書』、『情報メディア白書』、『月刊トイジャーナル』、『CESAゲーム白書』などをもとに作成した図表の統計値です。)
<!-- ところで前編集者Sさん,これって正確には何の数字,金額なの?それを後で書き足しておいてほしいんだけど…。あれかな?一年のこの国のゲーム産業の売上高? -->
また、2010年の時点の商学研究では、1997年を境に、ゲームソフト市場で競争する企業数が増加傾向から減少傾向に転じた<ref name="m289">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.289</ref>、とも言われています。
書籍『メイド・イン・ジャパンは終わるのか』にも、引用文「家庭用ゲームは日本がその本格的立ち上げを主導し」<ref name="m91">青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.91 </ref>と書かれているぐらいで、1990年代は日本のインパクトが強かったようです。
なお、携帯電話の分野で、日本は国際的な地位を喪失したのに対し、デジタルカメラとゲームは「現代」(参考文献の著作時2010年ごろ)でも日本が主要な地位にある<ref name="m91" />。
{{コラム|ゲームが産業の牽引役だと語った人物|
1998年頃、アニメ評論家の岡田斗司夫が、未来予想の一貫として、「これからゲーム機が、(パソコンではなく)家電の中枢になるだろう」というような内容の未来予想をしていました。たしか、岡田の著書『東大オタキングゼミ』(自由国民社、1998年)で、このような未来予想が読めます。岡田の東大での講義を加筆修正してまとめた書籍なので、実際の講義はその数年前に行われていたのだろうと思います。
岡田の東大での講義は東大生のその後の進路、官僚や大企業のビジネスマン達に大きな影響を与えただろうし、若手新進評論家として、この国の政治・経済人達も、その言論を参考にしただろう。
実際、2008年(リーマンショックあたり)くらいまでの日本の家電業界の投資は、ソニーがゲーム機のCPUを作ったりと、岡田の予想を参考にしているような面もありました。
ですが実際の2001年以降の家電業界の結果は予想とは少し外れました。まず
:* そもそも、冷蔵庫もエアコンも全然デジタル化(IoT化)されず、家電のほとんどが外部からのコンピュータ制御を必要としない状況。
:* 個々人が持ち歩いているデジタル家電は、携帯ゲーム機ではなくスマホになった。
:* パソコンは多くの家庭にいまだにインターネット用端末などとして残り続けている。
一方岡田は東大オタキングゼミで、98年当時の時点で任天堂が莫大な現金資産(たしか数千億円ほど)を持っていることに注目しています。
一般の大企業は、現金ではなく株券や不動産などの形で資産を蓄えています。しかし任天堂は、銀行口座の現金だけで数千億円という、非常に資金力の高い企業でした。今や日本を代表する世界的なゲーム大企業になっています。
また、日本だけでなくマイクロソフトのXBOXなど、実際に欧米の企業も昔はコンピュータゲームが産業の牽引役だと思って、先をこぞってゲーム機に参入していたわけでもある。岡田の未来予想は、決して根拠の無いものではなかったのです。
}}
{{コラム|読書について|
ゲーム業界と関連のない文献も、この教科書では出典として書かれていますが、これはこの頁の主要執筆者Sが、多量の市販本を読む以外に知的活動の方法を知らないことと、自分自身の文章の権威と信頼性を、著名人の威を借りて確立したいからでしょう。
ゲーム業界を志望するなら、ゲーム業界人の書いた本は少なくとも何冊かは読んでおくといいでしょう。
ネット上では、業界人ではないのにもっともらしく書かれた文章も多いですし、おそらく本Wikiの執筆者にも本格的なゲーム業界関係者は一人もいないでしょう。
業界人達のSNS発言ではなく、現代では書籍があるので、実際に書籍を手に入れて読むのがいいですね。書店で販売される書籍というのは、けっして著者だけの意見でなく、編集者や校正者、周辺の職業人達が査読をして、内容の信憑性を確認しています。
<!-- ニュース解説者の池上彰(いけがみ あきら)が、たしか2011年くらいのテレビ番組で言っていたことだと、編集者Sは言っている。 -->
何十冊も本を読むよりはプログラミングを書く実践のほうが重要でしょう。
『ゲームデザイン プロフェッショナル』著者であるFGOクリエイターも、ゲーム開発の書籍は読んでおくべきだと忠告しています<ref>『ゲームデザイン プロフェッショナル』、P234</ref>。また、ゲームデザイン本で学んだ知識は、ゲーム業界以外でも仕事術として活用できます。たとえば上司への業務報告の報告・連絡・相談(ホウ・レン・ソウ)などの考え方は、ゲーム業界でなくても活用できます<ref>『ゲームデザイン プロフェッショナル』、P332</ref>。
いっぽう、もし最新IT技術を勉強したいなら、読むべきは、ゲーム制作の解説本ではなく、そのIT技術の解説本など、そのものの書籍を読むほうが近道でしょう。
}}
===ゲームプログラミングは面白い。しかし、そんな楽な事ではない。===
ここでいう「プログラミング」とは、C言語などのプログラム言語による開発のことです。RPGツクールなど開発ツールによるゲーム制作の話は原則していません(本書『ゲームプログラミング』はあくまでプログラミングのための教科書です)。
さて、よくネットや、あるいは日常でも(C言語などによる)「ゲームプログラミングは簡単だよ。イラストやシナリオのほうが難しい。」、などという人がいますが、この発言の心は、「俺はプログラミングもイラストもシナリオも出来る凄い男だぜ。しかもプログラミングなんて簡単だし、むしろクリエイティブなイラストやシナリオの方に精力を費やす偉い奴だぜ^^」という、世間に良くいる武勇伝、自慢を語りたがる、インチキ親父が吹かしているだけなので、あまり真面目に取り合わないのが正解だと思います。
まず第一に、不当にプログラミングの価値を貶めている言説ですよね。
Visual C++またはVC# 、あるいは Direct Xなどを使ってプログラミングすることは、そんなに簡単なことではないでしょう。
ゲームプログラミングの入門書などには、初心者でも理解できそうな比較的簡単ないくつかのサンプルコードがありますが、それは初心者でも簡単に書けそうな技術だけを抜粋してるという、あくまで例外です。
RPGならたとえば、ドラクエ3のような戦争画面の行動順を処理するソート機能をつくるだけでも一苦労ですし、ほかにも道具・アイテムなどの自動整理をはじめとする標準機能を作るだけでも一苦労です。
決して上手い人のサンプルコードをコピーアンドペーストをして終わりという訳にはいかず(そもそも現状そのようなサンプルコードがネット上に無いですが)、もし仮にサンプルコードがネットに公開されていても、自作品に組み込む際にさらにそれをデバッグ(決してテストプレイの意味ではなく、実際にコード修正が必要になります)しなければならず、プログラミング言語の理解が必要です。
ゲームのプログラミングは決して楽ではないし、仮にもし楽だとしたら、じゃあゲーム会社のプログラマー職の人の仕事は何なんだ・・・という疑問につながりますよね(デマを言ってる人は、この疑問を脳内に都合よく無視しますが)。
ツクールやエディタのような制作ツールを使えば、C言語的なプログラミングは不要ですが、それはそのツクールなどのツールを開発している人達にプログラミングを肩代わりしてもらっているだけなので、決して「ゲームプログラミングが楽」、ではないでしょう。楽だというなら、じゃあツクール開発元の角川書店およびその発注先ソフトメーカーのプログラミングが楽だとでも言うのか・・・(デマを言ってる人はこの疑問を無視します)。
そもそもコンピューターゲームというのはプログラミングがなければ成立しないのですから、そのプログラミングの価値を貶めて平気な人は、コンピューターゲームにかかわる資格はないでしょう。
== ゲーム制作に関する留意点 ==
=== IT的な留意点 ===
====プログラミングなしでも同人ゲームを作れる====
自分でゲームを作る際、必ずしも、C言語などプログラム言語で記述する必要はありません。
プログラミングをせずに、ほぼマウス操作と会話メッセージなどの文章のキーボード入力だけでゲーム開発をできるようにするソフトウェアが、有料または無料で発表されています。
たとえば、RPGを作りたいなら、日本で発表されているソフトでは、『[[w:RPGツクール]]』や『[[w:WOLF RPGエディター]]』などのように、RPG製作に特化された開発ソフトがあり、大幅に開発の手間を減らせます。なお、『RPGツクール』は有料製品です。『WOLF RPGエディター』は無料ソフトです。
アクションゲームを作りたいなら、『[[w:アクションゲームツクール]]』があります。これらツクール製品は有料製品です。(なお、かつて『[[w: 2D格闘ツクール2nd.]]』というのがありましたが、しかし現在ではサポート切れのため、今現在の市販の十字キーコントローラーが初期設定では動かない、一部のボタンしか使えないなど問題点があります。)
また、ノベルゲームを作りたいなら、フリーソフトの『[[w:吉里吉里Z]]』などがあります。吉里吉里Zはソースコードが公開されており、オープンソースになっています。
:なお、とりあえず「ゲーム開発ツール」と呼びましたが、じつは呼び方は特に決まってはいません。「ゲーム制作ツール」と呼ぶ場合もあります。ゲーム開発ツールのことを「ゲームエンジン」と言う場合もありますが、開発ツール以外のゲーム用ランタイムのことも「ゲームエンジン」という場合があります。
:本Wikibooksでは、とりあえず、ツクールや吉里吉里シリーズやウディタ(WOLF RPGエディター)などのソフトの呼び方は、まとめて「ゲーム開発ツール」または「ゲーム開発ソフト」と呼ぶことにします。
C言語などによるプログラムは、上記のゲーム開発ツールを使わない場合の選択肢になるでしょう。
既存のゲーム開発ツールの仕様に不満を感じる場合に、「じゃあ自分でプログラムして作ろう」となり、プログラミングが必要になるわけです。
なお、上記の開発ツールはほとんどがWindows用のソフトです。MacやLinuxでは動きません。MacやLinuxで動作するゲームを作りたい場合は、別のソフトウエアを使う必要があります。
既存のゲーム開発ソフトを使わずにプログラムを組んでゲームを自作する場合、必ずしも既存のツールのような、ゲーム作品と開発ツールが分離された仕組みを再現する必要はありません。
一般的に初心者が、ゲーム開発ツールを作ることはほぼ不可能です。初心者は開発ツールを作ることは考えずに、まず1本、とりあえずゲーム自体を完成させてみましょう。開発ツールを自作したいのなら、まず先にゲーム1本を完成させたあとに、あとから開発ツールとゲーム作品の分離などに取り掛かるのが推奨です。
==== 商業ゲームの開発言語 ====
基本的に、現代の商業ゲームは、C言語で開発をする。
ただし、ファミコンの古いゲームは、アセンブラで開発されていた。ファミリーコンピューターからスーパーファミコンに至るまで、OSは搭載されていない<ref name="m289" />。
ではいつからC言語がゲーム開発に使われるようになったかというと、商学の学説では、プレイステーション(※ おそらくプレステ1?)の頃からだろう、と考えられている<ref name="m289" />。ただしこの時代でも、処理速度の高速化のためにアセンブラにアクセスする開発チームも少なくなかった<ref name="m289" />。
また、プレイステーションのOSは独自仕様である<ref name="m289" />。
カプコンなど一部の企業は、OSによる開発ではなく、移植性を高めるために自社製の内製フレームワークを用いて開発する。カプコンの場合、2010年頃は「MTフレームワーク」という自社製フレームワークを用いて開発を行っていた<ref name="m289" />。
{{コラム|ゲーム用のメーカー独自プログラミング言語について|
ゲーム開発ソフトには、ゲーム開発用の独自のプログラミング言語を持っている場合があります。このような機能の実現方法は、原理的には、ファイル入出力の関数を使い、テキストファイルの文字列を読み取って、文ごとにプログラム動作を設定・実行している、と、考えられます。インタプリタは、このような方法で作られています。
ゲーム製作ソフトでの独自のプログラミング言語はたいてい、コンパイル作業を必要としないので、おそらくインタプリタ方式でしょう。
基本的にWindowsの場合、実行ファイルに変換するには、Visual Studio というマイクロソフト社の配布している開発環境が必要です。
Visual Studio が開発環境を提供していない独自言語は、たいてい、インタプリタ方式となると思われます。
コンパイラ方式に比べて、インタプリタは処理速度が不利なので、適用できるジャンルや用途が限られます。たとえば3Dアクションゲームには、インタプリタ方式は不向きでしょう。
これらの独自言語を使うにしても、自分自身で独自言語を作りたいと思うとしても、この教本ではまず、既存のプログラミング言語を使ってゲーム制作を開始することを推奨します。
}}
====ゲームのプログラム言語の歴史====
ゲームを書くために利用される言語は多岐にわたっています。歴史的にはゲーム業界でも、[[C言語]]や、特に計算機のスピードが重要になる場面では[[w:アセンブリ言語|アセンブラ]]を利用してプログラミングを行うことが普通に行われていました。<!-- (文献)→-->そのため、ゲームプログラミングは通常のプログラミングと違った技能が必要であるように思われていました。
現在では計算機がある程度速くなったことや、ゲームプログラムの開発を複数人で行うことでテクニカルなプログラミングが避けられるようになったことにより、ゲームプログラミングは他の一般のプログラミングと同じような課題だと見なされています。
しかし、特にアクションゲームなどのリアルタイムでの画面書き換えが必要なゲームで、プログラムのスピードが重視されることは変わっていません。また、コンピュータの性能があがるにつれ、それらの性能を全て引き出すように表現手段が変化してきたため([[w:3次元コンピュータグラフィックス|3D]]、[[w:ポリゴン|ポリゴン]]などを参照)、状況によっては複雑で特殊なプログラミングが必要になることもあります。
===== 初心者が使えるプログラミング言語 =====
ゲーム開発において、一般にゲームショップなどで流通している商業ゲーム作品において、現在よく利用されているプログラミング言語として、[[C言語]]、[[CPlusPlus|C++]]、[[Java]]があげられます。
Windowsの3DエンジンのDirectXは、主にC++を想定しています。なので負荷の高いアクションゲームを作りたい場合、Visual C++での開発が安全でしょう。
しかし、ネット上のフリーゲームでは、C++以外の言語が使われることも、よくあります。
さいきんゲームエンジンとして有名なUnityは、言語としてはC#の文法を採用しています。
[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
市販の書籍では、Pythonによるゲーム開発を紹介した出版物もあります。ただし Python は原理的にインタプリタ方式であるために処理速度がC++に劣り、アクションゲームなど負荷の高いゲームを作る事を目指している場合は、将来的にはPythonからC++への装備変更が必要になるかもしれません。
===== ゲームに適さない(だろう)言語 =====
;Flash関係
例えば、かつて Adobe の Flash が、ブラウザで動かせるゲームを作る際に、よく使われていました。このようなwebブラウザ上で動くゲームのことを一般に、「ブラウザゲーム」と言います。ただし、現在ではFlashは廃止の方向です、すでにほぼ廃止されているといっていいでしょう。また、現状では、ローカルPC環境でのゲームをJavaScriptで作るのは、アマチュア段階では困難です。JavaScriptのアマチュアゲームと言う事例を聞きません。
;JavaScript
なお、JavaScript はクロスプラットフォームですが、しかし、セキュリティ上の理由などから、いくつかの機能(たとえばファイル入出力)がwebブラウザ上では使えないようになっており、そのため、JavaScript だけでゲームを作るのは、初歩的なゲームを除くと、かなり困難です。(おそらく、オンラインゲームでは、サーバー側でPHPやサーバサイドJavaScriptなどの別プログラムが走っていると思われます。)
セーブ機能の必要なゲームを作る場合は、JavaScriptでの開発は選択肢にない(セーブの実装には、JavaScript国際規格にはない非標準仕様を使いこなす必要があり、かなりの技術力を要するでしょう)。
=====ブラウザゲームの初歩的な原理=====
商品として流通するようなゲームや、高度な機能を持つブラウザゲームを作ることはとても難しく、このページでは手に負えません。そこで、このページでは、初心者が練習用につくるゲームを例に記述します。
webブラウザだけで動くのがブラウザゲームです。ブラウザゲームを作るのに使う言語の第一選択肢はJavaScriptです。サーバー側の処理が必要ならPHP,Python,Perl,Javaなどの言語の出番でしょう。
「ネットワークゲーム」は「ブラウザゲーム」とは意味が違います。
「ブラウザゲーム」は、パソコンにwebブラウザさえあれば、ネットワークに接続していなくてもゲームプレイできて、最後、クリアまでプレイできる作品もあります。
しかしネットゲームは、ネットワークに接続しないと、ゲームを開始することさえ不可能です。つまり、サーバの提供するゲームが「ネットワークゲーム」「ネトゲ」です。
もしPHPやPerlなどでゲームを作る場合、普通はネットゲームになる筈なので、作者がサーバを構築して提供する必要がありますし、プレイヤーにはゲーム中にサーバに接続する環境が必要になります。提供者は、サーバを用意したり、保守管理する必要がありますよね。サーバーがダウンしてしまうと、プレイヤーがゲームをできなくなります。
「PHP ゲーム」などの単語でネット検索したり、あるいは書店でプログラム言語の書籍や解説サイトを見ると、ときどきPHP・Perlなどの言語でゲーム開発しているものもありますが、一般的なダウンロード型のゲームとは違う筈なので、気をつけてください。
{{コラム|ソケット通信、ほか|
コンピュータプログラムからインターネットに通信するには、いくつかの方法がある。
C言語の場合はOSの提供するソケット通信といわれる機能を使う方法、
JavaScriptにあるHTTP通信の機能を使う方法、
などがあるだろう。
ただし、JavaScriptでゲームを制作するのは、セキュリティ上の制約などからセーブロードが標準的方法では困難など、とても制作が難しい。
よって本セクションでは、C言語にソケット通信を組み込むことの概要を説明する。
ゲーム制作初心者がソケット通信までする必要はないが、将来的には知る必要があるかもしれない。
本wikiではWindowsの場合については 教科書『[[WinSock]]』、
macやLinux / Unix や BSD の場合は 教科書『[[Unixソケットプログラミング]]』 で説明している。
Windowsとそれ以外のOSとで、ソケット通信の仕様が微妙に異なる。
ソケット通信では文字コードの問題がある。手元のパソコンの文字コード設定は、通信相手方の端末には反映されない。
Windowsの日本語版では、伝統的に Shift-JIS といわれる文字コードが使われてきたが、海外のWindows端末は日本の文字コードにあわせてくれないし、macやLinuxやBSDも同様に日本には合わせてくれない。
簡単な対処法として、ゲーム中では日本語を送受信しない、つまり半角の英数字と記号だけを送受信する、という道はある。
会員登録などのためにどうしても氏名や住所などの日本語を使う必要がある場合、PHP・Pythonなどサーバ言語に対応した「フレームワーク」があり、そのフレームワークが最初から日本語に対応、もしくは設定を少しいじるだけで日本語対応するので、それを利用すれば効率的かもしれない。
ゲームとは別途、サーバー側にフレームワークをインストールして、会員登録時にサーバー側でそれを使うようにすればいいだろう。
しかしゲーム内では日本語の扱いは非常に難しい、限定されるという事になるだろう。
C言語のプログラムにサーバサイドの言語・システムを組み込むのは難しいから、ネットゲームではどこかでソケット通信に頼ることになるだろう。
市販の本を探しても、そもそもソケット通信の書籍自体がめったに見当たらないし(ほんの少しだけ出版されている)、もし見つけても全く文字コードの問題の解決方法は紹介されていない(2021年現在)。
}}
====プラットフォ-ム====
;ライセンス料
一般に、プレイステーションや任天堂のゲームを開発するには、専用の機材が必要であり、そのため、ソニーや任天堂とライセンス契約しなければいけない<ref>『ゲームプランとデザインの教科書』、P.107 </ref>。
その契約に際して、ライセンス費用または料金と呼ばれるものを、ゲーム機開発会社の任天堂、ソニーに支払う必要があります。
現在でもソニーや任天堂のゲーム機用のソフト開発・販売には、ライセンス料が必要です。少なくともPS4やニンテンドースイッチのパッケージソフト開発には、「ライセンス費」が必要<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.120</ref>。
なお、書籍『ゲームプランナーの新しい教科書』によると任天堂やソニーのようにゲーム機を作っている会社のことをハードメーカーと言います。つまり、ゲーム機のハードメーカーにライセンス料を支払うという仕組みになっています<ref>『ゲームプランナーの新しい教科書』、P20</ref>。
また、スマートフォン向けアプリは、プラットフォーム使用料が掛かります。
書籍『ゲームプランとデザインの教科書』によると AppleStore, GooglePlayともに売上げの30%とのこと<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.121</ref>。その他のプラットフォームも、大体同じとのことです(参考文献の著作の時点では)。
Google やAppleのようにプラットフォームを提供している企業のことをプラットフォーマーと言います<ref name="gp244">吉冨賢介『ゲームプランナー入門』、P244</ref>。
昔からゲーム機のライセンス料は有料で高額であり、ソニーや任天堂の収益源のひとつになっている<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.267 </ref>。一方、パソコンゲームにはライセンス料が無いのが普通です<ref>青島矢一ほか『メイド・イン・ジャパンは終わるのか』、東洋経済、2010年8月12日発行、P.283 </ref>。
なお、ハードメーカーでなければプラットフォーマーでもないゲーム会社のうち、製造から販売までを手がける会社のことをパブリッシャーといい、たとえばカプコンやコナミやセガやスクウェア・エニックスやバンダイナムコなどがパブリッシャーです<ref name="gp244" />。
実は、必ずしもパブリッシャーが開発を手がけるとは限らず、スマホ向けアプリなどではディベロッパーといわれる開発専門の会社に委託している場合もあります<ref>吉冨賢介『ゲームプランナー入門』、P245</ref>。
;ポリコレ規制
Apple社のAppStore向けのスマートフォンアプリでは、アップロード後に、公開前にAppleによる審査があり<ref name="g139">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.139</ref>。、審査は欧米基準です。
GooglePlayは、公開前の審査はないが公開開始後に海外基準で審査されるので、それに違反していると配信停止になります<ref name="g139" />。
海外プラットフォームで販売・配布したい場合、「ポリティカル・コレクトネス」(政治的な正しさ)といわれる、海外の公序良俗の基準に配慮する必要があります<ref>『ゲーム作りの発想法と企画書のつくりかた』、P.235</ref>。
欧米の判断基準が、アジア諸国やアフリカの生活習俗に合致しない場合も多いのですが、欧米のIT大企業はその欧米基準での規制が政治的に正しいと考えているでしょう。「日本では、少し考え方が違う」と言っても、通用せず規制される場合も多い。
ゲームだけでなくテレビアニメでも、漫画ワンピースの海外アニメ版では、主人公側の若者がタバコを吸っているシーンをアメ玉に作画を変えられたり、ドラゴンボールに出てくるミスターポポという肌の真っ黒なキャラクターの肌を青く書き換えたり、色々な例があります。
ポリコレとは関係ない事例ですが、TVアニメーションのポケットモンスターで主人公のサトシ達がお握りを食べているシーンで、アメリカ版ではドーナツになっていたことがあります。これは、国による食文化の違いを示していますよね。
===プロトタイプ===
ゲームでは、曲や絵が良くても、ゲームとしては今ひとつ面白くない、という事は起こり得ますよね。
ですからむしろ、商業的なゲーム制作では、イラストは簡略なものを使ったうえで、プログラム中心の試作品(プロトタイプ)をいくつか作り、その中でゲームとしての面白さがあるものを、取捨選択したうえで商品化を考え、その後イラストや楽曲を詰めて完成度を高めていく、と、いう制作過程を取るようです。
書籍『ゲームプランナー入門』(吉冨賢介 著)によると、商業ゲーム界では、企画書に書かれたゲームが本当に面白いかどうか確認するために、「プロトタイプ」が作られます。プロトタイプの段階では、プログラマーと、企画の意図を考慮するためプランナーも関わります。<ref name="gp17">吉冨賢介『ゲームプランナー入門』、P17</ref>
イラストレーターは、プロトタイプの前段階あたりでイメージイラストを提供し、スタッフ間の共有イメージを作ります<ref name="gp18">吉冨賢介『ゲームプランナー入門』、P18</ref>。そしてプロトタイプ進行中は、グラフィック案の提案をしていきます<ref name="gcw56">蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P56</ref>。サウンドも同様、プロトタイプでは、曲調を固めていく段階です<ref name="gcw56" />。
:※時々あるトラブルとして、マイナーな同人ゲームや零細メーカーのゲームで、背景イラストや脇役キャラクターなど目立たない部分で他社のイラストが使われていることがあるようです。おそらく試作用に流用したイラストが、そのまま製品に混入したのでしょう。こういうトラブルがあるので、他社イラストの使用は試作であっても避けるべきです。
;実装検証
プログラマーは、そのゲームでコアになるプログラムやシステムやミドルウェアについて、プロトタイプ段階で実装検証を済ませておく必要があります。プロトタイプより前の原案の段階では、利用するミドルウェアの洗い出しをして、出来る範囲での基礎実験をしておきます<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P54</ref>。
ミドルウェアによっては使用料が発生するので、その点を事前に調べておく<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P55</ref>。
プロトタイプのうち、張りぼての例えば画面だけの物等を、「モックアップ」といいます。一方である程度遊べる状態まで作っているものを、「プレアブル」といいます<ref>STUDIO SHIN『ゲームプランナーの新しい教科書』、翔泳社、2018年3月10日初版第2刷、P251の図</ref>。
ゲームデザイン本ではよく「プロトタイプ」という表現が用いられるので、本ページではこの言葉を使うことにします。
{{コラム|商標権等|
知的財産権には著作権・商標権・意匠権などがありますが、商標権は特に強い権利であり、気を配る必要があります。
意匠権とは、建物や工業製品の外観に関する権利なので、ゲーム制作ではあまり気にする必要はないようです<ref name="gpd135">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.135</ref>。
「特許権・実用新案権」と「商標権」は、事業者によって国に登録されている権利で、かなり強力な権利なので、気をつける必要があります。
特許権や実用新案権とは、大まかに言えば、技術的な発明に関する権利です。商標が登録されているかどうかは、特許庁の『特許情報プラットフォーム』というwebサイト<ref name="gpd134">川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.134</ref>で確認できます。
商標をトリッキーな意図で登録する人も多く、自社でビジネス展開をする気がなかったり、他社の商品などでまだ登録されていない物を申請したり、そういうやや不正な登録申請でも認可されてしまう場合も多いです。
また、商標は業種のジャンルごとに分かれているので、たとえば携帯電話のジャンルが新たに追加された時代に、過去のゲームの商標を登録した人がいました。そのため携帯ゲームを出せなかったり、商標を買い戻したり、取り戻すための裁判をするのに時間とお金がかかってしまったり、様々な問題が発生します。<ref name="gpd134" />
著作権は、登録の必要がなく、著作をした時点で発生する権利です。
『ゲームプランとデザインの教科書』によると、こういう事柄にまだ慣れていない人によくあることなのですが、他人の個人サイトやSNSで公開されていた絵や曲などを、許可なく勝手に使う事例があるようです<ref name="gpd135" />。
二次利用を許可されてない著作物は素材として使えません。
そして見落としがちなのが、フォントの著作権です<ref name="gpd135" />。フォントにも著作権があります。
フリー素材と書かれていても、商用販売が禁止されている配布形態のものもありますので、気をつけましょう。
}}
{{コラム|アイデアの権利。アイデアとは盗まれるのか、盗むのか?|
商業ゲーム作家たちの、2022/1時点でのSNS発言によると、業界全体でみられることですが、会社外部の人がアイデアを一方的に投稿してきて、会社で作った作品にそのアイデアと類似点があったら、アイデア使用料を要求してくる、そのような問題に悩まされているようです。
そこでゲーム会社側では原則、
:送られてきたハガキやメールは、まずクリエイター以外の事務系の人間が読む。
:もしハガキなどにアイデアがあった場合、そのハガキを処分。
などの方策を取ると言われています。
また、偶然や何らかの理由でアイデアが一致してしまった場合に備えてのリスク回避として、事前に会社のウェブサイトなどで「弊社にアイデアが送られてきた場合、そのアイデアは弊社のものになります」のような宣言をしている会社も多くあると言われています。<!-- (以上、作家のSNS発言やそれを紹介したサイトの取材などのまとめ.)←出典を消すなってS氏はやたら云うんだけど,そんな重要な事かね?もちろん全くなくて,いい加減な事書いていいと言ってるわけではないけど… -->
ここで前編集者は娯楽産業の世界には厄介な消費者がいると言及しているけど、この前編集者自身がこのWikibooks で異常なまでに厄介な参加者なんだが、そろそろ人のふり見て自分を返り見るべきだと思うな。
法学的には、著作権法はアイデアを保護しません(『アイデア・表現の二分論』と言います)。
そして前編集者はアイデアに関して権利をどうこう言う人間を無知だと書いているけど、自分は至上の賢人だと思ってるようだね。
そしてこの人物は他者を愚弄する時は必ず自分の意見ではなく、権威ある人がそう書いたから、出典だからと宣う。
出典は岡田斗司夫氏の著作『東大オタク学講座』や『マジメな話』だそうだ。
まあ岡田氏ならかなり過激なことを書くのは事実だろうが,この前編集者S はその悪徳をさらに10倍に高めてこのWikibooks に記述する地獄のように厄介で無知で馬鹿な人間だ。
}}
任天堂『ゼルダの伝説 ブレス オブ ザ ワイルド』は、プロトタイプの段階ではイラストや音楽を組み込まずに(イラストは、代わりに大きなドットの塊などで代用する)作られている事がゲーム業界見本市イベント CEDEC 2017 で公開されています<ref>https://game.watch.impress.co.jp/docs/news/1078888.html 2020年11月25日に閲覧して確認</ref>。
プロトタイプの段階では、画像や音楽は発注せず、骨組み的なプログラムだけで、そのゲームのアイデアが「はたして本当に面白いか?」を、実際に社内の関係者にプレイさせてみて確認します。
因みにプロトタイプに関しては『[[高等学校情報/その他の技術的な話題#プロトタイプ開発]]』の記述も参考になる。
ここでいう「プロトタイプ」(試作品)とは、コンピュータプログラムのゲームとして動作するのが前提です。映画製作でいう絵コンテ試写のように、ゲームの試作では、なるべく早期に第三者が試作ゲームを遊べるように作っていく必要があります。
プロトタイプという言葉を使用すること自体が妥当かどうか。まず、書籍『ゲームプランとデザインの教科書』で使われている<ref name="gpd350">川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.350</ref>。
ニコニコ動画の経営者、川上量生が使っています<ref>川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日 第1刷発行、P.38</ref>。川上は角川書店も買収したので、おそらくそこ(カドカワ・RPGツクール販売元)でも使っているでしょう。
ゲームのプロトタイプの基本姿勢は、「汚く作って、やりなおす」です<ref name="gpd350" />。もちろん最低限のプログラムの知識、勉強は必要ですが、あまり知識収集や理解充実を気にするより、実際に作ってみることを優先したほうがいいようです。チーム制作をしている場合はプロタイプは赤ん坊であり、そのチームで育てていこう、我々の子供だという意識で接しているようです<ref name="gpd350" />。
勉強に関しては、汚くてもいいからまず工夫して作ってみると、何を勉強すればいいかが見えてきます。
英語では「quick and dirty prototype」という言葉があります<ref>川上大典ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日第1版第1刷、P.349</ref>。
書籍『ゲーム作りの発想法と企画書のつくりかた』によると、シナリオライター志望者が企画書やシナリオ案をメーカーに送りつけても、あまり効果的ではないようです。
それよりゲーム形式でシナリオを書いてしまうのがいいようで、「CHR:ヒロインA(私服)、表示」のような文章を織り交ぜて構成していくのが推奨<ref>『ゲーム作りの発想法と企画書のつくりかた、P.140</ref>。
参考文献のその章では、シナリオライター志望者に向けて語られていますが、プログラマーを目指すならどうすればいいでしょうかね。
プログラマー志望なら、サンプルゲーム、サンプルプログラムを作ってしまうのがいいかもしれません。
1990年代、週刊少年マガジンに不定期掲載していた読みきり漫画『ゲームクリエイター列伝』では、カプコン社のゲーム『バイオハザード』を扱った『バイオハザードを創った男達』の際、制作過程でゲームデザイナーが大幅な作り直しを判断して進行させた、という描写があります。(ただしWikiboooks一編集者の記憶、詳細はあいまい)。
のちの、ゲーム評論家の阿部広樹の評によると、むしろそれは劇的な大きな決断ではなく、ゲームデザイナーの日常の普通の仕事ではないか、と語られています。
どんな肩書の人間だろうと、すでに決まって進行していた方針をひっくり返すのは、かなりのストレスのある判断で指摘になりますが、一般に漫画や映画、あるいはNHKの仕事に関するドキュメンタリーでもそうですが、職業や職業者の物語では、過剰に対象を美化し、劇的な演出によって関係者を称賛し、英雄視する傾向があるように思います。
{{コラム|アイデアはアイデアで価値がある。でも、せっかくなら、それを試作して、形にしてみよう。|
ゲーム業界人広井王子は書籍のインタビューで、自分の社長としての人材評価は「0点」から始まる「加点法」だと語っていたようです。
『ゲームデザイン プロフェッショナル』著者も、文脈は違いますが「加点方式で物事を考える」と述べています<ref>『ゲームデザイン プロフェッショナル』、P224</ref>。
正直インチキなゲーム業界人の点数勘定などには全く興味ないが、そんな話とは全く別に、ゲーム制作の上で、実際に動く簡単なプロトタイプを作ってみることは間違いなく有意義な事でしょう。
アイデアはアイデアとして、思考や思想の展開としてありますが、それを具体的な形にしてみることは非常に楽しくエキサイティングで、意味ある活動ですよね。
}}
仕様書や設定資料を超えて、誰もが遊べる試作品は、意味のある企画行為でしょう。前編集者は、時間軸・動きの制作意図の明確化、という言葉を使っています。もちろん短くまとめること自体もなかなか難しいのですが、工夫を凝らして、ゲームプログラムを完成させることが重要な経験であり、思考の具体化でもあると思います。
===アルファ版===
アルファ版はプロトタイプとは違うもので、その後段階で、ゲームの全体像が分かる一部分を、商品に準じた形で作ることです<ref name="gp17" />。
アルファ版でもそのゲームが本当に面白いかどうか検証がなされます。サウンドやビジュアルは商品に近いほぼ完成化された形で取り込みます。
アルファ版の使用の結果、プロジェクト中止の決定がなされる場合もあります<ref name="gp18" />。
ベータ版とは、会社によって意味が多少違いますが(たとえば『ゲームデザインプロフェッショナル』と『ゲームプランナ-入門』とでも微妙に違う)、おおむね、とりあえずのゲーム、最初からエンディングまでのほぼ完成状態をひととおり遊べる制作物です<ref>『ゲームデザインプロフェッショナル』、P170</ref>。
細かいバグ修正はこれらの段階では後回しにします。
基本的に
:プロトタイプ→アルファ版→ベータ版→調整→デバッグ
の流れですね。
===プロトタイプ制作に必要な予備知識===
====数学は後回し====
ゲーム制作の作り始めにおいて、必要な数学や物理の予備知識は、それほど多くありません。
文献『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』によれば、数学や物理の習熟に拘って、それに多くの時間と精力を費やして勉強するよりは、3Dの勉強などで必要を感じたら、そのつど、その分野の数学や物理を学ぶのが効率的だと述べており、また可能なら実際にプログラミングでその理論を試してみると具体的に理解をしやすいと述べています<ref>蛭田健司『ゲームクリエイターの仕事 イマドキのゲーム制作現場を大解剖』、翔泳社、2016年4月14日初版第1刷発行、P88</ref>。
====C言語の予備知識は入門書1冊+αで十分====
C言語を使ったゲームは、予備知識はそれほど多くないので、あまり難しいことは考えず、まず実際にプログラムを書いて作ってしまう事優先にするのが正解なようです。
市販のC言語入門書で、配列や関数などの一般的な機能を一通り習得したら、あとはVisual C++ で映像出力とキーボ-ド入力のみを、1~2週間ほど勉強、そしてVisual Studioを起動してゲームを作り始める。
うまくいけば数か月以内に、パソコン用の非ネット通信のゲームを作ることができるでしょう。
ただ、ゲームプログラミングを試みる人は、必ずしもゲーム制作のみが絶対的な唯一の目標ではない可能性もあるので、それぞれの立場に応じて、座学を取り入れてみるのもいいと思います。
== 作業リストを作る ==
===作業リストの制作開始の方法===
さて、ゲームを作る時は、アイデアを頭の中だけに置いておくのではなく、文章に書きだしてみましょう。
そして、壮大な長大なアイデアではなく、1週間~1ヶ月ていどで成果の確認できそうなアイデアだけを書いてみましょう。
次にそのアイデアを、実際に動作するプログラム、ソフトウェア(つまりプロトタイプ)にするために、具体的などんな機能を持ったプログラム(簡単なものでよい)を制作しなければいけないか、自分のやるべきことのリストを、箇条書きで作ります。<ref>https://www.youtube.com/watch?v=J5FCZG7dfEY 2020年3月17日に閲覧</ref>
IT界ではこういうリストを「ToDoリスト」(読み: トゥードゥーリスト)とか「タスクリスト」といいます。このページではむしろ日本語で、「作業リスト」と呼んでみましょう。
さて、このリストを作るときは、作業項目は具体的かつ単純な目標に分割します。ですから例えば RPG の戦闘システムを作るときは、
*「戦闘システムを作る。」
と、あいまいに総体的に書くのではなく、具体的に、
*戦闘画面のメッセージ表示欄および標準メッセージを作る。
*「戦う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは後回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
という風に、作業項目を細かく分割していきます。
こうすることで、作業がひとつずつ比較的に簡単な要素に分解されていくので、楽になります。また、バージョン管理ソフトを使って管理している場合も、上記のような作業リストの分解をしておけば、各バージョンの概要を書く際にも作業リストの項目が転用できるので、一石二鳥です。
予定日は書かないほうがいいように思われます。スケジュールを管理したい場合は、別にファイルを作るといいですね。
そして書き出した項目を優先順位で並べたら、最初の作業リストは完成です。
===作業リストの更新===
プログラミングする前に作業リストを眺めて、そして上の項目から実際に作業を開始しましょう。
そして一つの項目を完成させましょう。
そして作業項目がひとつ終わったら、「【完了!】」等、そういう情報を、項目の前または後ろにつけます。備忘のための記録ですね。
たとえば、
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
こうします。
以前の記述を残したまま、その作業が終了したことを示しておくわけですね。
また、もし追加の作業が必要になったら、たとえばダメージ計算システムを作るために、ランダム計算が必要になって、自分がそのプログラム言語でのランダム計算に詳しくないなら、たとえば
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
::※3行目に追加されています。
と、必要に応じて項目を追加します。
さて、これから行う作業を検索しやすくするため、たとえば
'''やることリスト'''
*Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
'''完了した作業'''
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
の様に完了した項目を後回しにしたり、或いは
*【完了!】戦闘画面のメッセージ表示欄および標準メッセージを作る。
*【完了!】「闘う」コマンド選択欄を作る。(動作するコマンドはまだ「戦う」だけ。「逃げる」「魔法」などは音回し。)
*(現在→) Visual C++ でのランダム計算のとりあえず出来る方法について調べる。
*主人公1人用の「戦う」コマンド用のダメージ計算システムを作る。
*主人公以外の味方キャラのぶんの表示欄も戦闘画面に追加する。
*味方キャラが素早さ順に行動する処理を作る。
のように、(現在→)、を追加するのも良いでしょう。
つまり作業の記述をそのままに、どこまで進展しているかが分かる等に書き足していくわけですね。
==プロトタイプ制作における創作面の検討事項==
===ゲーム性===
「ゲーム性」という概念があって、これがあるからこそゲームは面白く、魅力的だと考えられています。
プレイステーション開発元のソニーもこれを重視していますし、一般的に多くのゲーム愛好者、関係者たちもその考えに同意するでしょう。
ではゲーム性とは何か?
ゲームのジャンルにもよりますが、「駆け引き」や「戦術」、これが「ゲーム性」だとよく言われます。
『ゲームプランとデザインの教科書』によると、ゲーム性とは、シューティングやアクションでは「対戦の駆け引き」、RPGでは「戦闘と物語の介入」、シミュレーションゲームなら「戦略性」だそうです<ref>『ゲームプランとデザインの教科書』、P152</ref>。
ただし上述の書籍によると、1990年代は今よりもゲーム性とシステムが重視されていたとの説明があるので、裏を返せば2010年以降の現代では、ゲーム業界ではゲーム性の重視の比率は1990年代よりも減っているかもしれません<ref>『ゲームプランとデザインの教科書』、P302</ref>。
『ゲームプランナー入門』(吉冨賢介 著)では、ゲーム性とは「課題や挑戦の仕組み」であると結論づけています<ref>吉冨賢介『ゲームプランナー入門』、P36</ref>。そして、この達成感こそが「ゲームならではの面白さ」だと述べています。
;アクションパズルゲーム「I.Q」
メディアクリエイターの佐藤 雅彦氏(「だんご3兄弟」や「ピタゴラスイッチ」等を手掛けている)が、初めてかかわるコンピュータゲームで、ソニー・コンピュータ・エンターテインメントとの共同企画で、のちに「I.Q」(1997年にシリーズ第一弾を発売)と呼ばれるシリーズに携わった時、プロトタイプが全くゲーム性のないものになってしまい、それをプレイしたソニーの幹部陣の顔色が非常に曇ってしまったようです<ref name="br67">川村元気『理系に学ぶ』、ダイヤモンド社、2016年4月21日第1刷発行、P.67</ref>。
ここでの悪い反応、薄い反応の理由がわからなかった佐藤氏が、階段の踊り場でソニーの新人に尋ねてみると、「それが、あの、ゲーム性がないっていうか・・・」と言われたと出典の対談集に書かれています<ref name="br67" />。
基本的に佐藤氏は、プロトタイプの企画を提案しただけですが、ソニーにはプロトタイプを作るための部署があるらしく、1~2ヶ月かけてそこでプロトタイプが作られたようです。
この問題の責任が誰にあるかは、大した重要な事ではありませんが、商業作品としてプロトタイプを作る以上は、どこかの段階でゲーム性を意識して、プログラムに盛り込む工夫が必要になるでしょう。
===ゲームの見た目とは?===
ふつうゲームのプレイヤーは、まず最初にそのゲームの「見た目」を判断し感受するでしょう。ですからその見た目のインパクト、興味を呼び起こす構成が必要になります。
例えばスーパーファミコンRPG『新桃太郎伝説』では、開発当初はドラゴンクエスト5 のようなマップ画面のトップビューUIでしたが、開発中にクォータービューの他社製RPGが発売されて高い評価を得たので、マップUIを(トップビューではなく)クォータービューに作り直したようです。このことは攻略本『新桃太郎伝説 究極本』に開発裏話として書かれています。
一方現在でもこの方向の試みは重要なようで、書籍『ゲームデザイン プロフェッショナル』の著者は、他企業の製品の画面と、自社の製品を目で見比べる分析方法で、自分たちの製品のUI の問題を見出しています<ref name="gdp199">『ゲームデザイン プロフェッショナル』、P199</ref>。
割と素朴で単純で即物的な見た目、「かっこいい」とか、「ぱっと見派手」等の要素が非常に重要なようです<ref name="gdp199" />。
商業としてゲームを作る以上は、ペイしなければ企業も事業の継続も維持できませんから、考慮せざるを得ない問題ではあります。
== ゲーム開発ツールを使う場合 ==
====開発ツールのライセンス条件====
ゲーム開発ツールのなかには、そのツールで開発したゲームソフトに義務として「この開発ツールで開発したソフトウェアは、ソースコードを必ず公開しなければならない」などの条件をつけている場合があり、このような条件を「開示義務」(かいじ ぎむ)または「ソース開示義務」などといいます。
ソース開示が嫌な場合は、開示義務のあるツールは使わないのが正解ですね。
ゲームに限らず、ソース開示を義務としている開発ツールは多くあるので、ライセンスには気を配る必要があります。
「有料ソフトの販売を禁止」とか「アダルト作品の開発は禁止」などの条件をつけている場合も、ありえます。
ですからゲーム開発において、ツールのライセンス条件の確認は、非常に重要です。
{{コラム|GPLライセンス違反|
GPL(ジーピーエル)というライセンスがあって、Linuxなどのオープンソースで使われています。このGPLを組み込んだプログラムは、ソースを公開しなければいけません。
ですから、ソース公開したくないプログラムには、GPLソフトウェアは組み込めません。
ゲーム業界でも、GPLライセンスのソフトウェアを組み込んでしまったために、呼出し元ソフトウェアでのソースコードの一部を公開することになったゲームがあります。2005年頃、『ToHeart2』という美少女ゲームが、xvidというGPLソフトを取り込んだ疑惑によって、GPL違反の疑いでソース公開になりました。([[w:ToHeart2#GPL違反とソース公開]])
GPLでも、たとえばLinuxサーバ上でソース非公開のアプリを動かすように、GPLのソフトウェアを非公開ソフトとは独立した状態で使う場合は、ソース公開の必要はない、と、考えられています。(これが必要有りとなると、オンラインのプログラムやネットゲームは全てソース公開しなければならなくなり、非合理な結果になる。)
特定のプログラム自体に、GPLソフトウェアのコードを取り込んだ時、ソースコード公開が必要になります。
}}
{{コラム|BSDライセンス他|
オープンソースの中には、どのような利用法であっても、利用者にソース公開を求めないライセンスもあります。BSDライセンスとMITライセンスはソース非公開で利用できます。
ゲーム制作ツールの吉里吉里Zは、修正BSDライセンスで公開されています。
もしライセンスのことがよくわからない、またはライセンスの学習に時間をかけたくないなら、オープンソースのツールを使うなら、BSDライセンスを使うのが安全です。
}}
[[w:DXライブラリ]]は、GPLでもBSDライセンスでもありません(DXライブラリ説明書「DxLib.txt」には、どこにも「GPL」とも「BSD」とも書いていない)。DXライブラリは単にソースコードが公開されていて、著作権者の「山田 巧」氏が著作権を保持しているオープンソースなライブラリです。
このように、ネット上でソース公開されているソフトウェアには、ライセンスの複雑な解釈を嫌ってか、「BSD」や「MIT」などのライセンス条件を名乗らないオープンソースソフトウェアもあります。
{{コラム|自作ソフトでソース開示|
昨今ではオープンソースやフリーソフトウエアの発展などの背景もあり、「自作ゲームのソースコードやソースファイルも開示しよう」と思うゲーム作者もいるかもしれません。
然しソースコードを開示していることが原因で、トラブルに巻き込まれる場合もあるかもしれません。自分の作ったゲームのコードが悪用され、トリッキーないたずらや嫌がらせ、誹謗中傷などを受ける可能性も全くないわけではありません。
そこでライセンスに、利用による損害に対する保証が無いことを明示するのは、ある程度有効でしょう。大抵の著名なフリーソフトウェアライセンスには、この条項があります。他者の悪意を完全に防ぎ失くすることは難しいのですが、ある程度の対策は見出されていますし、自身でも見出していく必要があるでしょう。
}}
====開発ツールを使用しないという事====
下記の理由(機能制限および移植性の悪さ)の問題から、あまり大規模な作品は開発ツールでは作らないでおくのが安全です。
大規模な作品の場合、Visual C++ などでコードを書いて開発することを推奨します。
=====機能制限=====
ゲーム開発ツールを使う場合、そのツールにもよりますが、「○○ができない」、つまり特定の目的を果たすための機能を持っていない場合があります。
Visual Basic や Visual C++ には普通にある関数でも、開発ツールには無い場合も多い。
また、もし、いったんはゲーム開発ツールを使って目的の機能を持ったシステムを作ったとして、さらなる機能をそのシステムに追加しようとするときに、大幅な作り直しが必要になる場合があります(拡張性の悪さ)。
システムがモジュール化されていても、そのモジュール部分では大きく改変する必要がある場合もあるでしょう。
ですからゲーム開発ツールによるゲーム制作では、あまり大作を作ろうとしないほうが安全です。開発ツールで作る作品は、比較的に小規模な作品に、とどめておくことを推奨します。
Windowsの場合、本来なら Visual C++ などを使って、プログラム文法のいろいろな事に留意しながらプログラムを書きますよね。開発ツールを使う場合、 Visual C++ のコードを書かずに、ほぼマウス操作だけでプログラムを作ろうとしているわけですから、何かしらの制限があります。拡張性の悪さは、プログラム文法などの学習の負担を減らすためのトレード・オフのようなものですね。
=====移植性の悪さ=====
また、もうひとつの問題点として、C言語への移植性の悪さがあります。
ソースコードが公開されていない開発ツールの場合、異なる開発環境にゲームのソースファイルを移植するのは、ほぼ不可能です(仮に、開発ツールのランタイムを模倣できたとしても、著作権などの法的な懸念が生じる可能性あり)。
ゲーム開発ツールで作ったソースを、Visual C++のソースに置き換えるのは、簡単にはできないし、ほぼ全面的に新たに書くことになるでしょう。
==イラストレーター、デザイナー==
ゲーム制作、業界において、イラストや音楽を作る部署、人物は、まとめて、"アーティスト"と呼んでいるようです。
ゲーム界の場合デザイナーというのは、プランナーやディレクターのことであり、管理職的な設計者のことで、美術的なクリエイターではない。design という英語には、機械建築の設計という意味もあります。
映像関係、画像系のアーティストはグラフィッカーと呼ばれることもあります。ムービー担当者、特にゲーム界では3D-CGの制作者をアニメーターと呼ぶことが多いようです。アニメーション業界では主に、手描きの原画、動画マンをアニメーターと呼びますが、最近は3D-CGアニメーション映画も多いので、すこし状況が変わっているかもしれません。
ゲーム業界とアニメーション業界、各会社企業、過去と現在で、「原画」「仕上げ」「絵コンテ」等、一般的な作業に関する言葉が、それぞれの状況で微妙に違った意味で使われることも多いですね。
…ところで前編集者はわざわざこの項目を作ったうえで、色々な場所での言葉の意味の違いを、クドクドと自分勝手な分かりづらい説明で長々述べた後、「混同しないように気をつけましょう。」なんて馬鹿馬鹿しい言葉で締めているんだけど、この人物の意図はどこにあるのだろう?
例えばデザイナーというのは一般的に、造形作品、図案、意匠を考案する人のことを言うのだから、ゲーム界の外の人間が多少その業界内での意味を取り違えても、それほど致命的なミスでもないし、罵倒、愚弄されるいわれもなければ、好き放題にその相手を罵倒、愚弄していいわけでもない。間違えて使っている人を見たら、その都度やんわりと教えてあげればいいだけじゃあない? だいたいその世界に現実に身を置いたら、そこでの言葉の意味、使い方なんて自然に覚えるものだし…。
それを得意げにこれが違うあれが間違いといちいち理屈書いて、いい気になって威張っているこの人物は何者なのだろう?
現編集者が思うには、この人物は、学問、知識、知恵、科学とは何かという事を、根源的に取り違えている、のだろう。
==操作性==
操作性について、親指と人差し指<!-- ←ここ,中指って書いてあったけど,こっちだよね? -->だけでボタンプッシュなどの操作ができるように作成するのが基本です。中指、小指、薬指はコントローラのホールドに使うぐらいです。人間工学的に、小指や薬指は力が弱いので、微妙な操作には向かないことが知られています<ref>川上大典ほか『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.48</ref>。
一般的にゲームプログラミングでは、
# プレイヤーからの入力を扱うことができる。
# ゲームが提示する内容を表示することができる。
入力と出力、この2点が機能として必要になります。
プログラミング言語とプレイヤーからの入力については歴史的にも、あまり変化がありません。言語では主に[[C言語]]、[[C++]]が用いられる。[[w:携帯電話|携帯電話]]向けのゲームでは[[Java]]が利用されましたが、これは携帯電話を提供する各社がJavaをアプリケーションの言語として選んだことによります([[w:iアプリ|iアプリ]]、[[w:EZアプリ (Java)|EZアプリ]]、[[w:S!アプリ|S!アプリ]]などを参照)。現在でもAndroidなどのスマートフォン向けでは、Javaが使われています。
パソコンゲームでは、プレイヤーからの入力には通常、キーボードかマウスを利用します。他に[[w:ジョイスティック|ジョイスティック]]や[[w:ゲームパッド|ゲームパッド]]が利用される場合もあります。家庭用ゲーム機では[[w:コントローラ|コントローラ]]が利用されることが多いのですが、[[w:ニンテンドーDS|ニンテンドーDS]]や[[w:Wii U|Wii U]]では[[w:タッチパネル|タッチパネル]]、[[w:Wii|Wii]]では複数の入力機器が提供されることが発表されています。各種入力機器をプログラムから扱う手法自体は、普遍性があり、入力機器ごとに大きく変化しない、と、考えられています。[[w:デバイスドライバ|デバイスドライバ]]、[[高等学校情報B]]には、プログラムから周辺機器を扱う方法について多少の記述があります。
画面表示のうち、3Dの表現は割合難しく、ある程度の数学(高校、あるいは場合によってはそれ以上)の理解が必要でしょう。2Dに関してはプログラムの面では、さほど難しい部分はありません。
==処理速度の問題==
基本的にプログラミングでは、関数を使って、処理をコンパクトにまとめ、定数ではなく変数で柔軟性のある操作をすることが求められますが、ゲームの場合は、この構造のせいで処理速度が低下することがあります。
現在のCPUの性能、速さはかなり高くなってはいますが、プログラム処理は無限に煩雑化できますから、やはり高度な処理を短時間でなすことが求められます。特にゲームは、リアルタイムの反応のタイミングが非常に重要ですからね。数学の指数計算についての雑学で、「新聞紙を42回おりたたむと、月に届く距離になる」というものがあります。(新聞紙の厚さ)*2^42、ですね。もっとも新聞紙の物性から言って、ほぼ不可能な操作ですけど^^;;。コードの内容、組み合わせによっては、このように計算量が指数関数的に膨大になってしまい、処理速度が非常に遅くなってしまう場合があります。
ですが、このセクションで後述するように、関数を用いる場合の解決策(※概要:あとでdefineやinlineに置き換え)があるので、プログラミングの初期のほうは、とりあえずバグを未然防止するために関数を活用するべきでしょう。
1980年代頃のファミコンなど古い時代のゲームでは、ストレージ容量(ハードディスク容量のこと)が、ボトルネックでした。「容量不足でイベントをいくつか削りました」と、当時のRPGなどのゲーム作家が述べるのは、ストレージ容量の不足のことですね。ただ当時のファミコンはROMカセットでハードディスクは無いので、まさにストレージ容量という言葉が適切でしょう。
しかし2010年以降の現代では、ボトルネックになっている要因は、ストレージ容量不足よりも処理速度です。
ゲームプログラミングに要求されるコード特性は、科学計算ソフトウェアや金融プログラミングなどの手法とは異なります。情報工学・情報科学で適切とされる「構造化プログラミング」などの歴史的に発展してきたプログラミング・パラダイムの理念とは反するようなコード開発方針になる場合もあります。しかしゲームプログラミングに限らず、限定されたハードウェアで特定の結果を速く得るためには、様々なトリッキーな手管が必要になるでしょう。
;ツクール等制作ツール
RPGツクールの制作元のカドカワ(アスキー社→エンターブレイン社→カドカワ(かつての「角川書店」) )では、PRGツクールでのアクションゲーム開発は推奨していません。アクションゲームの場合は、同じカドカワの「アクションゲームツクール」で制作するよう、薦めています。
アクションゲームとターン制RPG では要求される特性が大きく異なり、なかには、ほぼ対立しているような性質もあります。
ツクールやウディタでも、万能にあらゆることがスタマイズできるわけではなく、その制作ツールの特性に依存しますし、主に処理速度の低下しない部分についてユーザが創作できるようになっているでしょう。
多くのRPG制作ツールはマップ操作や戦闘画面の基本システムのルーチンそのものは、あまりカスタマイズできません。画像や音楽は挿入できますが、例えば戦闘プログラムなら、「コマンド」の命令文など一部の派生的な部分だけが独自に作れる程度でしょう。
ですから、ツクールでどうしてもアクションRPGを作りたい場合、基本システムの改造はかなり困難だろうし、別途、アクションRPGのような動作をするマップイベントを作成する・・・ぐらいでしょうね。
ツクールやウディタでターン制RPG以外のジャンルを制作するのには、実質的には限界があり、さまざまな制約が生じます。
;具体的な手法
初期段階では関数や変数を活用してプログラミングし、処理速度を高める必要がある箇所にだけdefineマクロ等を用い別の方法に置き換える。C++ならinline関数という前処理命令もあります。
通常の関数で記述していったソースコードを、あとから一括変換などでdefineマクロやinline関数などに置き換えることは比較的に容易です。
また、関数を経由しているので、マクロを使った場合でも比較的にバグが混入しづらくなっているかもしれません。(defineなどの前処理命令マクロは、用いるとバグを発見しづらいので、なるべくマクロの利用を避けるべきなのが、ゲームプログラミングに限らないプログラミングの定石です。)
一方、まったく関数を使ってないコードを、あとからdefineマクロなどに手作業で置き換えるのは、なかなか面倒です。
最終的には一括変換で置き換えることが出来ますから、途中の段階では、処理速度を気にせず関数を使うのがいいでしょう。
なお、defineマクロは、値の置換以外には用いないのが、プログラミングの定石です。このため、たとえば黒色RGB値の<code>10,10,10</code>といった配列にdefineマクロを使うべきかどうか悩みますが、とりあえずなるべく値周辺にだけdefineマクロを適用するようにするようにするのが良いでしょう。いっぽう、一般の命令文をdefineマクロで置き換えるのは、避けるべきでしょう。
たとえば、処理に0.5秒ほどの時間の掛かってもかまわないような場所は、どんどん、関数に置き換えていっても良いかもしれません。
アクション性のないゲームなら、関数をぞんぶんに活用できます。
ターン制RPGやシミュレーションゲーム、アドベンチャーゲームなど、関数を活用しやすいでしょう。
一方、アクションゲームなどでキャラクター操作中のコードのように頻繁に使って、しかもそのゲームの中心的なコードなら、そこは最終的には関数にしないほうが良いかもしれません。
このように、ゲームのジャンルによって処理速度に対する必要な水準が異なりますので、プログラミング時における関数などの利用の方針も異なります。
以上のように、何でも関数にすることは避けるべきです。関数は処理速度の問題がありますので、必要性のある部分だけ関数にするべき。関数を使わなくても、for文やif文などのブロックの構成を適切に組み合わせることで、コード中のmain関数以降の部分でコード共通化できることは色々とあります。
「共通性のあるコードだから」といって、大して長いわけでもないコードを関数に置き換える事は、速度維持には寄与せず、ゲーム制作のプログラミングとしては、悪手となるでしょう。
===2Dの画面出力===
画面出力の場合も入力機器の場合と同じで、これらを操作する方法はOSごとに異なっています。先ほどあげた GTK+, Qt, SDLなどのライブラリはクロスプラットフォームの画面出力を提供しているため、これらを利用することで全てのプラットフォームで動くプログラムを作ることができます。<!--画面出力を扱うためには近年の[[w:ビデオカード|ビデオカード]]の発展についても見る必要があります。しかし、ビデオカードの機能は2次元の描画に関してはあまりあらわには見えないので、この話題は3次元の描画を行うときに再び戻ってきます。-->
*[[ゲームプログラミング/ブロック崩し]]
*[[ゲームプログラミング/画面出力]]
==目次==
=== ジャンル別のプログラミング手法 ===
==== 3Dグラフィック ====
* [[ゲームプログラミング/3Dグラフィック]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
==== RPG ====
* [[ゲームプログラミング/RPG]]
==== アクション ====
※未作成
==== パズル ====
※未作成
==== シミュレーション ====
※未作成
=== ゲームのデバッグ ===
* [[ゲームプログラミング/デバッグ]]
=== 入力 ===
OSの種類によって、キーボード入力やマウス入力の受け付けのさいのプログラムの書き方は違う。
Windows API での具体的な手順は『[[ゲームプログラミング/入力]]』で説明する。
=== ゲームエンジン ※未完成 ===
* [[ゲームプログラミング/Unity]] ※リンク先ページの編集者が現状ではUnityの著作・調査を放棄中なので、調べ物としては役立ちません(2021年12月19日に本文を記述)。
=== 非プログラミングのゲーム製作の関連作業 ===
==== バランス調整 ====
*[[ゲームプログラミング/バランス調整]]
厳密にはプログラミングの話題ではないが、ゲーム製作では必要な知識なので、サブページで説明する。
:※ゲームデザインに関する記述をここに集積し分離したい、という編集者の意図もある。
==== ゲーム用の書類の書き方 ====
説明書や仕様書(しようしょ)の書き方については、『[[ゲームプログラミング/書類]]』で解説する。
== 未分類 ==
===Visual C++プログラムによる文字画像の出力===
Visual Studio付属のフォームデザイナ(VSの用意するGUI自動作成ソフト)によるGUIオブジェクト作成では、RPG用には使いづらい。いや、ひょっとしたら上手に使う方法はあるのかもしれないが、様々な理由で難易度は高い。
そこでまず、Visual C++で、フォームデザイナをなるべく使わずに文字や映像を出力する方法を考える。
選択肢は、幾つかある。
1.フォームデザイナを1つも使わない方式
*Windows APIで入力していく方法。(Wikibooksに『[[Windows API]]』の入門書があります。)
*DirectXで入力していく方法。DirectX自体はWindowsAPIを利用している。
2.1つだけフォームデザイナのパネルを使う方式
*フォームデザイナで「パネル」という画像表示機能のコンポーネントを一つ用意して、そのパネルで表示する画像をゲーム内のストーリーなどに応じて切り替えるだけで、すべての画像表示を行う。
フリーソフトでゲーム用ライブラリの『HSP』はWindows API を呼び出す仕組みになっています(HSP関連のサイトを見ると、Win APIプログラミングの解説をしている場合もある)。
フリーソフトでゲーム用ライブラリの『DXライブラリ』は Direct X を呼び出す仕組みになっています。そして、ゲーム開発ツールのひとつであるウディタのソースコードは、DXライブラリとVisual C++ を使って書かれていると、作者が公表しています(ただしソースコードは非公開)。しかし、ウディタを用いたRPGプログラミングでは DXライブラリによるコーディングはしない。ウディタにはコード入力の機能は無く、マウス操作や、キーボード操作、キャラ名称や会話文などのテキスト文字や数値の入力のみに対応している。
===乱数===
そもそも乱数とは何かという問題があるが、それは高度な数学的な議論になるだろうから、我々はその問題には深入りできない。
ゲームにおける乱数的な処理では、事実上ランダムな値にならず、演出や調整のためにアルゴリズムが介入している場合も多い。例えばゲーム中のくじで「外れ」続くと、当たり確率が変動し、次からは当たりやすくなるアルゴリズムなども良く使われる。<ref>『ゲームプランナー集中講座』、P232</ref>。
ゲームは娯楽であり、実用目的のシミュレータではないし、アルゴリズム介入で、確率的にもいんちきが多いので、あまり厳密なランダム性が問題になることは少ないだろう<ref>『ゲームプランナー集中講座』、P231</ref>。
例えばさいころというのは典型的な乱数器だし、ゲームにもよく使う物だろう。
無印C言語には標準的乱数関数 rand()があるが、これを乱数発生に使うことに批判的な意見もあるし、機能もやや不足していると見れる。
Windows64bit では int rand(void) の出力は 32bit 整数だろう。まず stand関数で初期化してから rand()を呼ぶごとに疑似乱数が帰ってくる。これの複数回の連なりが乱数列だね。帰ってくる値は0 以上 定数RAND_MAX の値以下。
例えばさいころの数値が欲しいなら、rand の返り値を6で割った後、余りに1足せば、とりあえずそれらしいものはできる。
RAND_MAXは rand()の属性として定数が与えられているだけだから(Windowsで0x7FFF)、この値の変更はできない。
まあこれでもそこそこいい加減な乱数として機能するだろうが、最近ではもう少し改良された、質の高い乱数関数もある。
また、改良された乱数関数は、乱数の範囲も指定できるから何かと使い勝手が良いし、バグを防ぐ効果もあるのだろう。
<syntaxhighlight lang="cpp">
Random^ saikoro1=gcnew Random();// Random^ でRandomクラスの変数を作っている。gcnewはインスタンスをつくるための演算子。
int detame; detame=saikoro1->Next(1, 7);// Next メソッドで「〇〇以上△△未満」の乱数を指定できる。「->」はメンバーアクセス演算子。
MessageBox::Show("目"+detame.ToString()+"が出ました。");
</syntaxhighlight>
↑例えば上述のコードは前編集者が示したものだが、これは .NETプログラミングですね。.NET のSystem::Randomクラスを使っている。.NETのクラスは普通、C#かVisual Basic で利用するので、Visual C++で使えるようにするには結構面倒な手管がいるが、その辺は読者諸兄、ヘルプやネット情報を参照して、適宜辿り付いてほしい。
C++ の場合はむしろ、 #include <random> を宣言してそこで使える関数を使用するほうが簡単でしょうね。この場合でも、乱数としての精度も高いし、帰り値の範囲指定もできる。
===画像のちらつき===
画像がひんぱんに変化するアプリでは、画面が、ちらつく事がある。画面のちらつきは、ゲームのように、画像を凝視するアプリでは、かなり利便性を損なう。
キャラクターが1歩移動するだけで、画面全体がちらついたりする場合もあり、かなり、プレイヤーの不満になる。
これは、ダブルバッファ(「裏画面」と、良く言われる)という技術で、解決を図る。
Direct Xの用語では「スワップ チェーン」と呼んでいる。
.NET Framework開発環境の C++や C#でもダブルバッファの機能があると解説されている。いくつかのGUIオブジェクトのプロパティで、ダブルバッファの設定項目がある。
しかし前編集者が実験したところ、この機能を有効に使って確認することはできなかったとの指摘がある。ひょっとしたら何らかのマイクロソフトの解説に間違いがあって、工夫次第では利用できるかもしれないが、少なくとも今現在のこのページでは、その問題に関するリファレンスは提供できない。
そこでやはり、以前の項目と同様、Win32 API または DirextX の利用をこのページでは考えたい。
前編集者は、.NET Framework のフォームデザイナでは、ちらつき自体は解決できそうだが、グローバル変数の共有が困難だったり、アプリ内から終了コマンドが使えない、などの難点があると指摘している。
ただ現編集者はこの2点に関しては、解決策はあると思うが、しかし特に調査はしない。
前編集者は、.NETプログラムでゲームを作る難点をいくつも上げているが、おそらくどれも、.NET の仕様や全貌に精通すれば解決できるように思えるが、そもそもその全貌がかなり広大なので、解決の道のりは長いだろう。
そこで少なくともこのページでのWindowsゲームプログラミングは、Win32 API を利用したものになるだろう。
==セーブ、ロード、データベース==
===セーブ機能とロード機能の作り方===
ゲームでもシリアライズ機能が必要なことは多いだろう。数値(HPなどの各種パラメータ現在値)や文字列(例えば、プレイヤーの作成したキャラクターの名前)や現在地やフラグ状況などなど、セーブの機能は欲しい。一番簡単な方法は、C言語の fopen 関数のテキストファイル書き込み機能で、テキストファイルとしてセーブすることだろう。
Windows API には CreateFile関数 があるが、テキストファイルでの素朴なセーブは一番簡単で単純なセーブ法だろう。そしてテキストファイルを読み込んでプログラムに各種変数を配置して、ロードとする。
書き込みとしては、一番単純なC言語記法では、fprintf ですかね。C++としての書き込みをしてもいいし、読み込むのも、一番基本的な方法で。基本Cだとしたら fscanf で、この関数でテキストの数値も変数として読み込めるはずですよ。場合によっては atoi関数 で文字列→数値の変換をすることもありますかね。
基本的にデータファイルは、OS もアプリケーションも、テキストファイルとバイナリファイルの2分類で考えるでしょう。でもテキストファイルだってバイナリの集まりなんですが、テキストを扱うファイルだけ特別視していると考えていい。
そして多少それらしいデータを作りたいときは、バイナリファイルで作るという事になるでしょう。
バイナリファイルでもデータとしてのファイルと、OS が機械語または何らかの仮想的な機械語として扱う実行ファイルがある。それらのバイナリは種類に応じて多くは冒頭にファイル識別子の情報があるだろうし、OS や アプリケーション側で工夫を凝らして、特定の条件を満たす場合しか動作しないようにしているだろう。そしてバイナリファイルを扱うときは、セキュリティの安全性も考慮するだろう。
基本的にプログラム側は何でもありだが、識別子の判別その他、ある程度様々な考慮をしないと、困った事態が起こり、プログラマーが責任を問われることも起こるかもしれない。
まあその時はいつものように口先だけで謝り、それでも許してくれなかったら、腹をかっ割いて死んでお詫びすれば、世間の人たちは美事な武士道精神と言って、口々に褒め称えてくれるだろう^^。←もちろんこれは冗談^^;;;。
市販のパソコン用ゲームや同人ゲームでは、テキストファイルではなくバイナリでデータ保存するゲームの方が圧倒的に多いだろう。その方がそれらしいしかっこがつく。ゲーム開発ツール側自体も、そうなっている場合が多い。RPGツクールもウディタも、セーブデータの形式はバイナリ。
テキストデータは基本エディタで開けるが、バイナリデータも内容によっては結構ぐちゃぐちゃの状態で開ける。バイナリデータはバイナリエディタで開ける。バイナリエディタのリードオンリーモードやバイナリビューアみたいなものがあれば、データーを壊さないで結構安全にデータ調査できる。
データ内容を秘匿したければ、バイナリ化だけではなく、暗号化も必要になるかもしれない。
===機能の整備===
セーブ&ロード機能の実装時には、まずセーブ機能から作るのがやりやすいという。
しかし最終的には関係関数の整備は、ロード機能が基盤となるだろう。
データや変数を、一定のスタイルでセーブして、一方で正しいスタイルでロードする、この機能が必要なわけですよね。
シリアライズされたデータを、型を決めたうえで配置しなければいけないから、ロードのプログラムの方が複雑に、面倒になる。
結局データのシリアライズは、ロード機能が基盤となり、その機能の作りやすさが、セーブ機能の作りやすさも支配するようだ。
== ゲーム中の特殊イベント ==
*[[ゲームプログラミング/特殊イベント]]
RPGやシミュレーションゲームで、1回しか起きない特殊イベントを作りたい場合もありますね。例えば日本の中世の戦国シミュレーションゲームで、「桶狭間の戦い」が3回も起きたら困りますよね。まあ起きるなら起きてもいいけどね^^。信長君には敦盛を3回舞ってもらいましょう^^。
さて、リンク先ではその話題についての叩き台、「こうプログラミングしたら、いいんじゃない?」、という事を説明しています。
== スケジュール管理の教養 ==
[[File:Tokai Hairo.jpg|thumb|500px|ガントチャートの例:東海発電所の廃止解体工程]]
個人でのゲーム開発には全くの不要な知識ですが、スケジュール管理表といわれる技法がいくつかあります。
「作業責任分担表」(TRM: Task Responcibility Matrix)といわれるスケジュール表から、
それをグラフ的に図示したガントチャートといわれる表を作って、その表を見て作業計画を判断する方法です
<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
{| class="wikitable" style="float:left"
| 仕事
| 担当
| 状態
| 開始
| 終了予定
| 終了日
|-
| 仕事1
| 田中
| 済
| 2021/10/03
| 2021/10/10
| 2021/10/10
|-
| 仕事2
| 田中
| 仕掛
| 2021/10/11
| 2021/10/13
|
|-
| 仕事3
| 鈴木
| 済
| 2021/10/05
| 2021/10/08
| 2021/10/08
|-
| 仕事4
| 山田
| 未着手
| 2021/10/13
| 2021/10/17
|
|-
|}
{{-}}
ガントチャートでは普通、横軸に日程をとります。
ゲーム業界でもガントチャートの横軸は日程です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
ガントチャートとして図示することで、どこがボトルネックなどのリスク要因になりやすいのかが、一目瞭然です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.65</ref>。
なので、それを見越して、スケジュール管理をします。
このTRMとガントチャートは、IT業界だけでなく建築工事でも使われるので、
社会人の知識のひとつとして知っておくと良いです。
ガントチャートによるボトルネックの洗い出しも、建築学の教科書でも良く教わる内容です。
よく住宅リフォーム工事などで、一般人でも建築業者の提示するガントチャートを見る機会があります。
新人の段階でそんなの書く機会はないかもしれませんが、しかし知っておくと上司からの命令が理解しやすいので、
知っておくと得でしょう。
== ストーリー作成などの順序 ==
ストーリー作りに限らず、ゲーム作りではゲーム全体を先に作るのが先決です。ニュアンスは違いますがアトラス社いわく(ゲーム開発では)、おおむね「ゲーム全体に全体に血を回すのが先」といった内容の格言があります<ref>[https://news.denfaminicogamer.jp/projectbook/191030a/2 『【ゲームの企画書】『ペルソナ3』を築き上げたのは反骨心とリスペクトだった。赤い企画書のもとに集った“愚連隊”がシリーズを生まれ変わらせるまで【橋野桂インタビュー】』2019年10月30日 11:30] 2020年12月1日に閲覧して確認.</ref>。
プレイヤーが見たいのは、ゲーム全体のストーリーやテンポといったゲームの全体像です。細部は、あくまで補助的であり、そういった細部に対するプレイヤーの興味も、あくまでオマケの範囲でしかないのです。
さて、暗黙の前提として、ゲームのストーリーは、システムと連携・調和したものでなければなりません。
このため、ゲーム作家によっては、先にシステムを決めてから、あとからストーリーを作るような方法論を採用しているクリエイターもいます<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、2018年11月1日 第1版 第1刷、P.306</ref>。
さて、ともかくゲームのストーリー作成は、なんらかの方法で、全体像を先にきめてから、あとから細部を作っていきます。
これを実現するための方法として、いくつかの方法があります。
ドラマの脚本などで使われる、「ハコ書き」という方法を使う人もいます。全体像に当たる「大ハコ」を記述してから、「大ハコ」→「中ハコ」→「小ハコ」と記述していく方法です<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.184</ref>。
そのほか、別の方法としては
:* エンディングを大まかに先に作る
:* 機能の実験を簡易でいいので事前にしておく(※プロトタイプの項目を参照)
:* 使用頻度の高い部分から作る
のような方法もあるでしょう。
そのほか、書籍『ゲームプランナー入門』で紹介されている事例だと、アルファ版(α版)を中盤から作り始めています<ref>吉冨賢介『ゲームプランナー入門』、P17</ref>。α版の製作目的の一つとして、そのゲームが本当に面白いかの検証や(駄目すぎたら製作中止)、改善するとしたらどこかの洗い出しが目的ですが、中盤だとそのゲームの全体像がわかりやすいので検証しやすいからのようです。
作品やジャンルや製作目的などによって、エンディングからか中盤からか、どこから作り始めるかは若干の違いはあるでしょうが、ともかく必ずしも冒頭部から作り始める必要がないということです。
;エンディングおよびラスボス戦闘を早めに作る場合
まず、ゲーム用のストーリー(ゲームシナリオ)の作り方ですが、学校などでの作文の書き方の順序と、ゲームシナリオの書き方の順序は、違います。
作家にもよりますが、ゲームシナリオを作る場合、エンディングを早い時期に作る人もいます<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
文献『ゲームプランとデザインの教科書』によると、シナリオでなくシステム面についても、先にゲーム全体のクリア条件を決めてから、あとから各ステージなどのクリア条件を決めていくことが多いようです<ref>川上大典 ほか著『ゲームプランとデザインの教科書』、秀和システム、、2018年11月1日 第1版 第1刷、P.253</ref>。
では、シナリオの仮のエンディングについて考えていきましょう。このエンディングは、当面の仮のエンディングなので、あまり作りこむ必要がありませんが、しかしエンディングが必要です。
エンディングのシナリオと、キャラクターの性格づけの設定があることにより、そのゲームで何を主人公に目指させるべきなのかが、作者にハッキリとします<ref>畑大典 ほか著『ゲーム作りの発想法と企画書の作り方』、総合科学出版、2020年11月19日 第1版 第1刷発行、P166</ref>。
ともかく、方法は作家ごとに色々と違いはありますが、そのゲームの全体像を何らかの方法で決めるのが先です。
また、ゲームでは最後のラスボス戦がそのゲーム中でもっとも高負荷だったり、全部のシステムが組み合わさってたりしますので、先にエンディングを作っておくことで、そのゲームで最大負荷の状態を検証する事が出来ます<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
また、3Dゲームでは、RPGなら戦闘シーン、アクションゲームならアクションシーンが、一般的に、最も高負荷です<ref>ntny著『ローポリスーパーテクニック』、ソフトバンククリエイティブ、2010年2月16日 初版 第5刷、P28</ref>。
処理オチの確認とかも、この方法で確認できます。
また、ラスボス戦およびエンディングは、そのゲームの大きな見所のひとつであり、ほぼ最大の見所がラスボス戦およびその前後です。
いっぽう、中盤などは、比較的に重要性が下がります。
なので、スケジュール遅延や容量不足などで、ストーリーを短くしないといけなくなった時などは、ラスボス戦以外の場所を削ることになります<ref>[https://www.youtube.com/watch?v=kAUkSNhH410 『ゲームの開発順序について解説します』] 2020年8月30日</ref>。
よって、ラスボス戦などは削る可能性が少ないので、先にラスボス戦を作っておけば、たとえスケジュール遅延などをしても、先に見所を作ってあるので、早くリリースしやすくなります。
{{コラム|イラストなど異分野での類似事例|
似たような、先に結末を決める事例は、イラスト技法にも存在します。
1995年ごろ、イラスト雑誌『コミッカーズ』(1995年 コミッカーズ季刊 夏号)に、当時の人気漫画家&イラストレーターの藤島康介がインタビューされたのですが(なお、その号の表紙は別の漫画家(唯 登詩樹))、
藤島はインタビューにて、おおむね内容『よく若い漫画家さんから相談で「先生みたいに女性の長い髪を書くとき、毛先を書くのが難しいです。根元は書けるのに」との相談を受けるのですが、
僕(藤島)は髪を描くときは毛先から始めて根元に向かって描いてます』みたいなインタビュー返事をしました。
こういうふうに、大切なのは頭の使いようです。要するに、ズレるのが怖い場所は、先に位置決めをすればいいのです。髪の房(フサ)の根元と毛先だったら、ごく一部の場所を除いて、読者の目線では毛先のほうが目立ちます。
だったら、作画の際の誤差は、読者には気づかれない根元の部分に押し付ければいいのです。
よくよく考えれば、イラストに限らず機械製図とかでも普通にそういう位置決めの優先指示の記法はあるのですが、
しかし世間の人は、なかなかそういう発想を異分野に応用できません。普通の人はついつい、実際の髪の伸びる順序どおりに根元から描いてしまいます。
}}
* 目標の提示
ゲーム中の目標の明確化は、シナリオの設計手法としてだけではなく、たとえば各ステージ目標の提示などは、プレイヤーをゲームに引きこむ手法にもなります。
というか、文献『ゲームプランナー入門』によると、もしゲームの目標や課題が満足に語られていないと、プレイヤーは最悪、「?」となり、コントローラーを置いてゲームを中断してしまいます。なので、設計の際、各ステージやエリアなどの冒頭で、そのステージの課題や目標などを明示する必要があります<ref>『ゲームプランナー入門』、P39</ref>。
ファミコンの古いアクションゲームだとゲーム本編では目標は語られていませんが、しかし説明書などではキチンと目標が語られており、実際にスーパーマリオブラザーズの第1作目では説明書では目標がクッパを倒してピーチ姫を救出することだと語られています<ref>『ゲームプランナー入門』、P54</ref>。
=== その他の開発順序 ===
==== チュートリアルの細部は後回し ====
:※ 特に出典は無いですが、技術系の仕事では常識的な考え方です。
RPGやシミュレーションゲームなど、プレイヤー視点では、ゲームの始めのほうに操作説明などのチュートリアルのイベントがありますが、しかし、実はチュートリアルの細部は、作るのが後回しになる場合が多々あるかと思われます。
なぜなら、ゲームで仕様を変更するたび、チュートリアルも変更の必要が生じるからです。このため、チュートリアルのとりあえずの完成の時期は、けっこう後回しになります。
よほど仕様の単純なゲームなら別ですが、そうでない場合、あまり開発初期からチュートリアルの細部を作りこみすぎないようにするほうが安全でしょう。
そもそも、チュートリアルをゲーム本編に組み込み必要もありません。たとえば説明書などで、細かい説明を代用する事だって可能なわけです。
チュートリアル部分に深刻なバグが発生してないかとか、逆に本編ゲーム中にチュートリアルが異常起動しないかなどの確認のために、開発初期からチュートリアルを組み込んでも構いません。ですが、おそらく、最終的なチュートリアルの完成時期は、仕様やゲーム全体像が本当に完成・確定したあとの時期なので、ゲーム本編の完成間近の時期になるか、もしくは本編完成後になるでしょう。
== 古典ゲームと技術限界 ==
ゲームを作る際、過去の名作ゲームを参考にしようと思うでしょうが、
しかし過去のゲームの設計は、当時の性能の限界に影響を受けているので、
果たして現代のコンピュータ性能の飛躍的に上昇した時代でも過去の設計をそのまま参考すべきかは、
やや検討の余地があるでしょう。
歌舞伎などの古典技芸の伝承の格言で『師を見るな、 師が見ているものを見よ』という教訓があると言われています。
このセクションでは、主に1980年代のファミコン時代のゲームを例に説明します。
=== スプライト ===
ファミコン時代の昔のゲーム機には、一画面に表示できるキャラチップ数(敵チップも含める)に上限がありました。
一画面中に表示できる限界は、だいたい、マリオが一画面中に数十人ぶんです。(実際の数値については、本ページでは触れない。説明の本質には関係ないので。)
ファミコンでは、このような仕組みを 「スプライト」と呼んでいました。(実はマリオ1体の表示の時点で既に、いくつかのスプライトの小単位を合成したものになっているのですが、説明やややこしくなるので、このページでは触れません。)
ともかく、実は昔のゲームのステージ設計は、スプライトの制限を前提にしたものになっています。
極端なハナシ、もしたとえばシュテイングゲームなどで、動く敵100体をボムで一瞬で倒せるようにしたゲームを設計しようとかファミコン時代に思っても、
ファミコンではすでに敵100体の表示の時点でグラフィック性能的に原理的に無理なのです。
どうしても敵100体を表示したい場合、表示のタイミングを変えます。
たとえば、
:1タイミング目では0~10体目までのAグループを表示、
:2タイミング目では11~20体目までのBグループを表示、
みたいにして、タイミングを変えることで、なんとか表示するのです。
このため、画面上に動くキャラクターが多いと、一瞬、ほかのキャラが消えるのは、裏側でこういうタイミング切り替えの処理が行われているからです。
説明の都合上、本ページではキリのいい「10体目」までと 上記の例では表現しましたが、実はファミコンの制限はもっときびしく、横1列上には8体目までしか表示できないと言われています。(しかもマリオ1体自体が、じつは2体×2体の計4体チップを使っているといわれる。なのでマリオ5体は同一ライン上には表示できない。)
なおシューテイングゲームの場合、敵チップだけでなく、敵味方の双方の弾丸もチップを利用しますので、実際の制限は上記の数値例よりも、もっと厳しいでしょう。
また、プレイヤー視点ではキャラクター1人にしか見えていなくても、背の高いキャラクターなどはキャラクター2体以上に相当するなど、注意しなければならないこともあります。
だからファミコン時代のアクションゲームで、巨大ボスのいるステージでは、ボス以外の敵が出現しないのは、おそらくですが、プレイヤー視点では1体のボスに見えても、内部プログラム的には敵チップを何体ぶんも利用しているのでしょう。
しかも巨大ボスは、ゆっくりとしか動きません。
おそらく、そのゆっくりとした時間内にVRAMを書き換え中だったのでしょう。
日本ではコトワザで「ウドの大木」みたいな言葉があるので、なんとなく巨大ボスがゆっくりと動いても不自然ではないかもしれませんが、よくよく考えたら現実世界の大男はけっこう動きが早いです。(レスラーやヘビー級ボクサーなどを考えれば分かるでしょう。)
=== 書き換え速度と背景グラ ===
ファミコンのマリオでは、書き換えの手間を省くために、一説には、たとえばマリオ1の地上ステージの世界の空の青色は、実はほとんどの場合、マリオが横スクロールしても空の青色の部分は書き換えをしておらず、横スクロールする前の青色をそのまま使いまわしていると言われています。
なぜそれで効率化できるかというと、ステージ中の障害物はほとんどのステージの場合で、画面の比較的に低い位置に障害物があるので、その低地の障害物だけを書き換えすれば済むからです。
だからファミコン時代では、こういう理由から、ステージの背景グラフィックや、障害物配置なども決まっているでしょう。
だから果たして、現代でもそれを過去の名作のステージ構成を踏襲すべきかどうかは、分かりません。もちろん、仕組みを分かった上で真似るのなら、それは特に問題ないでしょう。
=== アナログテレビの にじみ ===
ブラウン管では、細かすぎるドットは表示が、にじみます。ゲームに限らず、テレビアニメや一般の実写番組などでも同様、にじみます。(どのように、にじむかは、専門的なので説明を省略する)
だから、ファミコン時代から、だいたいプレステ1時代のゲームのグラフィッカーは、このことまで意識してドットを描いているはずです。
ともかく、液晶テレビとブラウン管テレビでは、同じ画像データでも表示結果が変わります。
レトロゲームから勉強する際は、ファミコン〜プレステ1時代のレトロゲームでは、データ上の解像度よりも実際のディスプレイ上の映像は細かいことに気をつける必要があります。
たとえば滲み(にじみ)を意図的に利用することでテレビの解像度以上の表現をしていたりしていました。
また、ファミコンのドットは縦横の長さが縦方向と横方向とで長さが違うので、そこまで考慮して、グラフィッカーは絵を描いています。
また、ドットの図形的な細かさだけでなく、色についても、にじみによって、当時のゲーム機の色用のビット数の限界を超えた表示をファミコン時代から行っていました。
つまり、同じドットの黄色の単色でも、そのドットの幅が1ドットか2ドットかで、テレビ上で表示される色が違います。「色が違って見える気がする」ではなく、実際にブラウン管のディスプレイ上では色が違うのです。言い方を変えると、ブラウン管テレビでは元の画像データ通りには色は表示されていません。(さらに縦方向と横方向とで色のにじみ方が違うが、専門的すぎるので、説明は省略する。wiki書くために調べるほうも大変なので。)
なので、もし現代の人がファミコン当時のゲーム作品のグラフィックを参考にする際は、このことに気をつける必要があります。一番、手軽なのは、そもそもグラフィックの細部については参考にしないことです。
これはつまり、もし公式エミュレーターなどでファミコン時代の古いゲームを、現代の液晶ディスプレイ用のゲーム機でプレイしても、エミュレーター側で過去テレビのグラフィック特性の再現のための特別な工夫をしてないかぎりは、実はグラフィックの表示結果が当時のものとは異なるわけです。
一方、パソコン市場では、ノートパソコンの普及し始めた1999年頃には液晶ディスプレイのものが比較的に安価で出て来たので、この頃からパソコンゲーム市場では次第にブラウン管のにじみを考える必要が無くなったでしょう。
なお、アナログテレビはそもそもテレビ自体の解像度が低いので、プレステ2時代あたりからのゲームには合いません。だから、プレステ2時代あたりからは、あまりブラウン管の特性を考える必要はなくなります。
逆に言うと、あまり指摘されないことですが、プレステ2時代の当時の人が当時の最新ゲーム機をプレイするには、もし既存のアナログテレビを使い続けていた家庭は、テレビ受像機そのものを買い換える必要があったという亊です。
一応、家電量販店などでテレビ用のアナログ/デジタル信号の変換機などを購入してテレビに接続するなどして使えば、デジタルテレビ用のゲーム機もプレイ可能ですが。
だからアナログ放送自体は2010年くらいまで続いたとはいっても、あまり当時のゲーム機をアナログ用テレビでプレイしていたとは考えにくくはあります(プレイヤーの好みによる)。
アナログ停波以降の時代である2010年以降の現代では、もうテレビ番組の受像でもブラウン管は一切用いられていないので、もはや現代のコンテンツ制作では特に考える必要はありません。
ブラウン管自体のドットの縦横が違っている。
このため、ブラウン管を前提にしたゲーム機やパソコンはそれに対応するために画像データ側のドットの縦横比が違っている。
ゲーム機やパソコンの種類、さらにはアーケードゲームの基盤といったハードウェアの種類ごとに、コンピュータ側でのドットの縦横比の管理は違っている(らしい)。このため、移植のたびに、ドットは書き直しになったようだ。
古いゲームの制作では「ドット用紙」という方眼紙のような印刷書面がある(らしい)のだが、そのドット用紙の時点で1マスの縦横比が少しだけ違い、1マスが長方形である。1ドットだけでは長方形であるのに気付かないかもしれないが、しかし「ちりも積れば山になる」ように、何十や百ドットも積み重なれば、縦横の長さは大きく違ってくる。
現在のパソコン用のドットエディタ(という画像制作ツールがある)は1ドットが正方形であるが、しかしファミコン時代は1ドットが(ドット用紙の時点で)少しだけ長方形である。(なお、画像制作ツールそのものの作り方については、『[[ゲームプログラミング/画像ファイルの作成プログラム]]』で説明する。ゲーム制作では普通は必要ないが、知識として。)
ファミコンの色数制限は52色から4色×4パレット(1パレットあたり4色)を使えると言われている<ref>[https://mynavi-creator.jp/blog/article/history-of-2dcg-designer
『2DCGデザイナーなら知っておきたい2DCGゲームの歴史』 2017/8/21 マイナビクリエイター編集部 ] 2021年12月30日に確認. </ref>。しかし実際には、4色のうち1色は透明色として利用される色であり、全パレット共通の色である(なので3×4=12色になることのいなる)。スプライトのパレットとは別に背景のパレットがあるので実際には、もっと16色以上の多くの色数が一画面内で使えるが、しかしその他のさまざまな制限があるので、合計で一画面内で25色が使えると言われる(12 × 2+1 = 25)。
しかし実際には、ブラウン管の滲み(にじみ)を利用しているので、当時のプレイヤーには1パレットだけで描かれた1キャラのキャラチップ内でも3色以上の多くの色が見えているだろうし、画面全体でも25色内にない色がプレイヤーの目には映っていることになるし、もしかしたら52色にない色がプレイヤーには見えているかもしれない。なお、スーパーファミコンの色数制限は32,768色から16色8パレットであると言われている。
レトロなゲーム機では、さらにメモリ容量やストレージ容量などの制限もあり、けっして仕様上の最大色数を気軽に利用できたわけではないだろう。こういう制限もあったからか、ネットではファミコンの色数が「4色」やら「8色」、スーパーファミコンの色数が「16色」や「256色」などとも言われることもある。
{{コラム|「ドット絵」とは|
よく世間には、ファミコン時代のゲームの、ゲーム中での絵柄のことを「ドット絵」という人がいます。プレステ1やセガサターンのポリゴンによって、「ドット絵」が無くなったと思っている人もいます。
しかし現実には、プレステ以降でも、顔ウィンドウの顔グラフィクや、キャラチップなどのグラフィックでは、その制作時にドット単位のグラフィック指定は行われています。
たとえば装備品で武器の横に小さい剣の絵などのアイコン画像が書かれている作品などもありますが、こういったアイコン画像もドット単位の指定で描くでしょう。
こう指摘すると、「プレステ1以降のゲームは解像度が高い」とかよくわからない反論をする人がいますが、しかし「ドット」という工学用語のどこにも、「解像度が低い」とかの意味はありません。また、「ドット」というのをブラウン管ディスプレイの映像だと思ってる人もいます。
しかし、液晶ノートパソコンの普及した2001年以降の液晶モニターの時代ですら、
「液晶のドット欠け」などのように「ドット」という用語は使われます。
「ドット」というのは、けっしてゲーム用語ではなく、「液晶のドット欠け」のように電子工学などですでに意味が決まっているので、ゲームオタクの戯言(ざれごと)は「ドット」の意味には無関係です。
さて、プレステ1以降のゲームでもキャラチップなどでは、ドット単位の指定が行われるのでした。
それどころか、携帯ゲームソフトでは、ガラケーの時代から既にドット単位の指定は現役の手法であり、スマホゲーム時代の現代でも現役です。
だから「ドット絵には魅力がある」とかいって、ファミコン時代のゲームばかりあげる人は、こういう現役のドット絵作家の努力が目に入らない人ですので、なるべく信用しないほうが良いと思います。
また、画像編集のフリーソフトまたはシェアウェアで、現代でも「ドット エディタ」と呼ばれる種類の画像制作ソフトがあり、少なくとも2D同人ゲームの制作ではよく使われます。
ツクールやウディタのドット絵を作る場合でも、ドットエディタを使って作るわけです。
ゲームに興味なさそうな人が「ドット絵」をレトロゲームの絵という意味で使うのは仕方ないかもしれませんが、しかしゲーム通みたいな顔して「俺ってけっこうオタクなんだぜ」みたいなフリしてるのに、レトロ的な用法で「ドット」という言葉を使う人はアレです。
おそらく、本当はけっしてドット絵が好きなんじゃなくって、単に自分の子供時代の思い出が好きなだけだと思います。
ニュアンスは違いますが、アニメ評論でもそういう話があります。1990年代後半に岡田斗司夫と誰かの対談で(おそらく書籍『マジメな話』での対談)、
「アニメの黄金期はいつか?」というよくあるアニメオタク談義について、
対談相手が言うには、
よく「70年代だ」「いや80年代だ」とかで議論が始まるが「いや12歳だ」というオチが有名だと。
}}
=== アナログテレビの焼きつきなど ===
あまりゲーム評論では指摘されないのですが、
このほか、ファミコン時代はテレビ受像機がアナログのブラウン管ディスプレイなので、
あまり長時間、同じ色をディスプレイ上の同じ位置に表示し付けていると焼きつきが起きる可能性があるので、
ステージごとにコンセプトになる背景色を変えたり、
あるいはステージの背景色を黒にしたステージを増やしたりとかの工夫も、必要だったかもしれません。
ゲームではないですがパソコンソフトなどの古いソフトは、こういったディスプレイの焼きつきの事を考えており、だからスクリーンセーバー機能の搭載など何らかの対策をしています。
ともかく、あまり、特定の色ばかり続けて使いすぎないようにする工夫が必要だったでしょう。
アナログテレビは西暦2010年のアナログ停波する時代まで使われていたので、焼きつき問題はファミコン以降のプレステ1~2時代のゲームにも関係するでしょう。
ネット上にはデマで「ブラウン管だと焼きつきが起きない」(×)というデマがあるが、しかし西暦2001年くらいの筐体パソコンのモニターはまだブラウン管が多かったし、その時代からすでに焼きつき防止のためにスクリーンセーバーがWindowsに搭載されていた。だからデマ「ブラウン管だと焼きつきが起きない」(×)にダマされないように。
なお、現代のテレビ受像機には、焼きつき防止のためにすでに「ピクセルシフト」という機能があって、
これは画面上の映像の表示位置をタイミングによって微妙にズラす機能です。こういう機能がすでに搭載されているので、わざわざゲームソフト側で実装する必要はない。そもそも液晶モニターは、焼きつきが起きにくい。ただし有機ELはどうだか、まだ新しい技術なので分からない。
== 脚注 ==
<references />
== 関連項目 ==
* [[ゲームプログラミング/コンピュータゲームの種類]]
* [[XNAを使用したシンプルな3Dゲームの作成]]
* [[プログラミング]]
* [[w:ゲームプログミング]]
{{DEFAULTSORT:けえむふろくらみんく}}
[[Category:ゲーム]]
[[Category:情報技術]]
{{NDC|007.64}}
opjl1makvf03j1m44936dnva9uwbrsa
受験ガイド
0
4259
205818
159884
2022-07-25T06:00:21Z
133.78.37.245
wikitext
text/x-wiki
{{Pathnav|メインページ|試験|入学試験|frame=1}}
小学校・中学校・高等学校・高専・大学・大学校等の入試受験に関する記事。
* [[小学校受験ガイド]]
* [[中学受験ガイド]]
** [[中学受験参考書]] {{進捗|25%|2013-12-06}}
* [[高校受験ガイド]]
** [[高校受験参考書]] {{進捗|25%|2013-12-06}}
* [[高専受験ガイド]] {{進捗|00%|2013-12-06}}
* [[大学受験ガイド]] {{進捗|00%|2013-12-06}}
** [[大学受験参考書]] {{進捗|00%|2013-12-06}}
** [[日本の大学受験ガイド]]
** [[海外の大学受験ガイド]]
** [[外国の大学受験ガイド]]
* [[大学校受験ガイド]] {{進捗|00%|2013-12-06}}
== 関連項目 ==
* [[小・中・高等学校演習]] {{進捗|00%|2013-12-06}}
[[Category:入学試験|*しゆけんかいと]]
ageuf1nhu8f573gcpjj2xrwqw2eqoyk
民法第136条
0
5042
205799
200945
2022-07-24T20:36:12Z
Rhkmk
66092
/* 判例 */
wikitext
text/x-wiki
[[法学]]>[[民事法]]>[[民法]]>[[コンメンタール民法]]>[[第1編 総則 (コンメンタール民法)]]>[[民法第136条]]
==条文==
([[w:期限|期限]]の利益及びその放棄)
;第136条
# 期限は、'''債務者の利益'''のために定めたものと[[w:推定|推定]]する。
# 期限の利益は、放棄することができる。ただし、これによって相手方の利益を害することはできない。
==解説==
期限の利益とその放棄について規定している。
==参照条文==
*[[民法第135条]](期限の到来の効果)
*[[民法第137条]](期限の利益の喪失)
==判例==
*[http://www.courts.go.jp/search/jhsp0030?hanreiid=52323&hanreiKbn=02 不当利得請求事件](最高裁判例 平成15年07月18日)[[利息制限法第1条]]1項,[[利息制限法第2条]],[[利息制限法第3条]],[[民法第488条]],[[民法第489条]],[[民法第491条]]
{{前後
|[[コンメンタール民法|民法]]
|[[第1編 総則 (コンメンタール民法)|第1編 総則]]<br>
[[第1編 総則 (コンメンタール民法)#5|第5章 法律行為]]<br>
[[第1編 総則 (コンメンタール民法)#5-5|第5節 条件及び期限]]
|[[民法第135条]]<br>(期限の到来の効果)
|[[民法第137条]]<br>(期限の利益の喪失)
}}
{{stub}}
[[category:民法|135]]
e2j0q8aq778to6iglqg5ecuck3vvqm9
HTML/HTML5
0
14190
205828
190370
2022-07-25T07:26:33Z
Ef3
694
/* audio要素とvideo要素 */ Fix bugs;autobufferなる属性は、html living standardにない。
wikitext
text/x-wiki
{{Wikipedia|HTML5}}
MediaWiki編集におけるhtml5対応については [[w:Help:ウィキテキストにおけるHTML]] を参照。
'''HTML5'''(エイチティーエムエルファイブ)とは、[[HTML]] 4.01の後継としてW3Cにより2014年に勧告された規格である<ref>2019年にW3CとWHATWGは「HTML Living StandardをHTMLとDOMの唯一の標準とし、W3Cは今後HTMLとDOMに関する標準の策定を行わない」旨合意したことを発表しました。この事により2021年6月現在のHTML5の(唯一の)標準は、HTML Living Standardのみとなっています。</ref>。
== HTML4.01からの変更点 ==
=== 構造の改善 ===
人が見てもコンピュータが見ても解読しやすい構造とするため、デザインに関係する部分はスタイルシートに記述し、要素や属性でデザインを指定することはしないという姿勢がより徹底された。そのためfont要素やcenter要素などいくつかの要素が廃止され、table要素におけるwidth属性やalign属性なども廃止された。HTML4.01で非推奨であったb要素やu要素などは復活している(非推奨が外された)が、要素の意味づけが変更されている。header, main, section, article, nav, aside, footerなどセクショニング要素が新たに追加され、文書構造をより簡潔に記述できるようになった。
=== マルチメディアへの対応 ===
マルチメディアへの対応も目的の一つであり、audio, video, embedなどの要素が追加された。
== HTML5ソースのサンプル ==
<syntaxhighlight lang="html5" line>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>簡単なページ</title>
</head>
<body>
<header>
<h1>簡単なページ</h1>
<nav>
<ul>
<li><a href="#">ホーム</a></li>
<li><a href="#">このサイトについて</a></li>
<li><a href="#">実績</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h2>はじめに</h2>
<p>このサイトは簡単なページのサンプルです。</p>
<article>
<h3>概要</h3>
<p>このページはサンプルです。</p>
</article>
</section>
<aside>
<h2>コラム</h2>
<p>コラムのような余談はASIDE要素に記述します。</p>
</aside>
</main>
</body>
</html>
</syntaxhighlight>
== DOCTYPE宣言について ==
[[w:文書型宣言|DOCTYPE宣言]]は、ドキュメントの種類を宣言します。HTML4では、この要素内で「!DOCTYPE html」以降にDTDによるスキーマが参照する仕様でした<ref>DTDでスキーマを参照しているのでHTML4はSGMLに基づいていると言えます。</ref>。しかしHTML5では <code><!DOCTYPE html></code> だけにするように決まりました<ref>DTDをDOCTYPE宣言に含まなくなったことにより、HTML5は最早SGMLではなくなり。この事は使用できる文字列実体参照の相違などに影響します。</ref>。
== audio要素とvideo要素 ==
audio要素はオーディオを再生、video要素は動画を再生する。embed要素やobject要素による埋め込みと異なり、この方法ではプラグインを介さずブラウザの機能で直接マルチメディアの再生を行うことが出来る。ただし、ブラウザにより対応フォーマットは異なる。
;audio要素とvideo要素のマークアップ例:<syntaxhighlight lang="html5">
<!-- audio要素の場合 -->
<audio autoplay controls>
<source src="example.ogg" type="audio/ogg">
<source src="example.mp3" type="audio/mp3">
(ここに未対応環境への代替コンテンツ)
</audio>
<!-- video要素の場合 -->
<video width="320" height="240" autoplay controls>
<source src="file.ogv" type="video/ogg">
<source src="file.mp4" type="video/mp4">
(ここに未対応環境への代替コンテンツ)
</video>
</syntaxhighlight>
<!-- バージョンが古すぎます。
=== 対応フォーマット ===
{| class="wikitable"
! !!colspan="4" |動画ファイル !!colspan="2" |動画ファイル
|-
! !! Ogg !! MP3 !! WAVE !! AAC !! Ogg !! H.264
|-
| Mozilla Firefox 3.6 || ○ || - || ○ || - || ○ || -
|-
| Google Chrome 4 || ○ || ○ || - || ○ || ○ || ○
|-
| Safari 4 || - || ○ || ○ || ○ || - || ○
|-
| Opera 10.50 || ○ || - || ○ || - || ○ || -
|}
-->
== canvas要素 ==
{{Main|JavaScript/Canvas}}
=== 概要 ===
[[w:canvas要素|canvas要素]]はダイナミックなビットマップ(ベクター)画像を描画する。二次元コンピュータグラフィックスはCanvas APIにより実現され<ref>https://html.spec.whatwg.org/multipage/canvas.html#2dcontext </ref>、ハードウェアアクセラレーションされた二次元及び三次元コンピュータグラフィックスは[[w:WebGL|WebGL]]を用いて実現される。
;書式
<syntaxhighlight lang="html5">
<canvas id="canvas" width="320" height="240">
(ここに未対応環境への代替コンテンツ)
</canvas>
</syntaxhighlight>
[[JavaScript]]を使用するとcanvasに画像を描くことができる。
;挿入するJavaScriptコード例
<syntaxhighlight lang="javascript">
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillRect(100, 100, 200, 200);
</syntaxhighlight>
JavaScriptは下記のようにcanvas要素と組み合わせて使用できます。
;HTMLでのJavaScriptとcanvasの組み合わせの例
<syntaxhighlight lang="html5">
<!DOCTYPE html>
<html lang="ja">
<head>
<title>簡単なページ</title>
</head>
<body>
<canvas id="canvas" width="320" height="240">
</canvas>
<script>
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillRect(100, 100, 200, 200);
</script>
</body>
</html>
</syntaxhighlight>
なお、上記のコードは、実行するとブラウザ画面に青い長方形を描きます。
ctx.fillStyle = "rgb(0,0,200)";
では色指定を行っています。0〜255の範囲で赤・緑・青の色見をそれぞれ指定しています。
ctx.fillRect(100, 100, 200, 200);
の書式は、上記htmlコード例の設定なら、
ctx.fillRect(始点x座標, 始点y座標, 横幅, 縦幅);
です。(第3引数と第4引数は、終点の座標位置ではないので、混同しないように注意しましょう。)
=== 簡単な動画の例 ===
アニメーション処理などをしたい場合、円や四角などの簡単な図形を動かすだけなら、JavaScriptと要素を連携させれば、ウェブブラウザで簡単な図形がアニメーションする動画を表示させられる。
詳しい解説は、たとえば[https://developer.mozilla.org/ja/docs/Web/API/Canvas_API/Tutorial/Basic_animations モジラ公式サイト"Basic animations" ] などにある。もしかしたらブラウザの種類によって挙動が変わるかもしれないので、実用の際には都度、実機で確認のこと。
下記のコード中にある<code>setInterval</code> の書式と内容は
setInterval(function, delay)
::function で指定した関数を delay ミリ秒ごとに繰り返し実行、
である。
;[https://plnkr.co/edit/mIHg6c4ay3DbpMHz?open=lib%2Findex.html 簡単なcanvasアニメ]:<syntaxhighlight lang="html5">
<!DOCTYPE html>
<html lang="ja">
<head>
<title>簡単なアニメーション</title>
</head>
<body>
<canvas id="canvas" width="600" height="500"></canvas>
<script>
let ctx = canvas.getContext("2d"),
count = 0;
setInterval(() => {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = `hsl(${360*count/255},100%,50%)`;
ctx.fillRect(count, count, 40 + count/2, 40 + count/2);
count++;
count %= 256;
}, 5);
</script>
</body>
</html>
</syntaxhighlight>
== ページ内がいくつかの文書に分割される場合 ==
=== header要素 ===
header要素はヘッダ(ページ上部に表示される部分)を書くために利用する。
=== footer要素 ===
footer要素はフッタ(ページ下部に表示される部分)を書くために利用する。
=== aside ===
余談やサイドバーなど、メインでない要素であることを示す。
=== main ===
main要素は、そのページの主要な要素であることを示す。
main要素により、ヘッダやフッタ、サイドバーなどと区別することができる。
== nav要素 ==
nav要素は、その項目が目次や索引であることを知らせる。
[[w:パンくずリスト|パンくずリスト]]を作るために用いることができる。
== HTML4対応ファイルを改修する場合 ==
HTML5で廃止された機能を使う場合(たとえば frameset などはhtml5で廃止された)、HTML4に準拠してHTMLファイルを書く場合があります。
このような場合にも、header要素やnav要素を使いたい場合、html4仕様と矛盾しないでhtml5を意識したコードを書く方法があります。
それは class 属性を利用してdiv要素で、
<syntaxhighlight lang="html4strict">
<div class="header">
</div><!-- /header -->
</syntaxhighlight>
のように書く方法です。
こうすることで、将来もし、html5のどんな要素に対応するかを説明できるので、集団作業では色々と便利です。
なお、<nowiki> <!-- --></nowiki> は非表示タグというもので、コメントを書くのに使われます。その非表示タグ内に書かれた文字はブラウザ画面には表示されません。
== 脚注 ==
<references />
== 外部リンク ==
* [https://html.spec.whatwg.org/multipage/ HTML Living Standard]
[[Category:HTML|5]]
{{stub}}
6b8gsx3qw451056jc5j51qmqykq1sqs
205830
205828
2022-07-25T07:37:56Z
Ef3
694
/* 簡単な動画の例 */ [TODO:この例では、setInterval()を使って render() を(進捗によらず)キックしていますが、requestAnimationFrame()を使って書き直すべきです]
wikitext
text/x-wiki
{{Wikipedia|HTML5}}
MediaWiki編集におけるhtml5対応については [[w:Help:ウィキテキストにおけるHTML]] を参照。
'''HTML5'''(エイチティーエムエルファイブ)とは、[[HTML]] 4.01の後継としてW3Cにより2014年に勧告された規格である<ref>2019年にW3CとWHATWGは「HTML Living StandardをHTMLとDOMの唯一の標準とし、W3Cは今後HTMLとDOMに関する標準の策定を行わない」旨合意したことを発表しました。この事により2021年6月現在のHTML5の(唯一の)標準は、HTML Living Standardのみとなっています。</ref>。
== HTML4.01からの変更点 ==
=== 構造の改善 ===
人が見てもコンピュータが見ても解読しやすい構造とするため、デザインに関係する部分はスタイルシートに記述し、要素や属性でデザインを指定することはしないという姿勢がより徹底された。そのためfont要素やcenter要素などいくつかの要素が廃止され、table要素におけるwidth属性やalign属性なども廃止された。HTML4.01で非推奨であったb要素やu要素などは復活している(非推奨が外された)が、要素の意味づけが変更されている。header, main, section, article, nav, aside, footerなどセクショニング要素が新たに追加され、文書構造をより簡潔に記述できるようになった。
=== マルチメディアへの対応 ===
マルチメディアへの対応も目的の一つであり、audio, video, embedなどの要素が追加された。
== HTML5ソースのサンプル ==
<syntaxhighlight lang="html5" line>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>簡単なページ</title>
</head>
<body>
<header>
<h1>簡単なページ</h1>
<nav>
<ul>
<li><a href="#">ホーム</a></li>
<li><a href="#">このサイトについて</a></li>
<li><a href="#">実績</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h2>はじめに</h2>
<p>このサイトは簡単なページのサンプルです。</p>
<article>
<h3>概要</h3>
<p>このページはサンプルです。</p>
</article>
</section>
<aside>
<h2>コラム</h2>
<p>コラムのような余談はASIDE要素に記述します。</p>
</aside>
</main>
</body>
</html>
</syntaxhighlight>
== DOCTYPE宣言について ==
[[w:文書型宣言|DOCTYPE宣言]]は、ドキュメントの種類を宣言します。HTML4では、この要素内で「!DOCTYPE html」以降にDTDによるスキーマが参照する仕様でした<ref>DTDでスキーマを参照しているのでHTML4はSGMLに基づいていると言えます。</ref>。しかしHTML5では <code><!DOCTYPE html></code> だけにするように決まりました<ref>DTDをDOCTYPE宣言に含まなくなったことにより、HTML5は最早SGMLではなくなり。この事は使用できる文字列実体参照の相違などに影響します。</ref>。
== audio要素とvideo要素 ==
audio要素はオーディオを再生、video要素は動画を再生する。embed要素やobject要素による埋め込みと異なり、この方法ではプラグインを介さずブラウザの機能で直接マルチメディアの再生を行うことが出来る。ただし、ブラウザにより対応フォーマットは異なる。
;audio要素とvideo要素のマークアップ例:<syntaxhighlight lang="html5">
<!-- audio要素の場合 -->
<audio autoplay controls>
<source src="example.ogg" type="audio/ogg">
<source src="example.mp3" type="audio/mp3">
(ここに未対応環境への代替コンテンツ)
</audio>
<!-- video要素の場合 -->
<video width="320" height="240" autoplay controls>
<source src="file.ogv" type="video/ogg">
<source src="file.mp4" type="video/mp4">
(ここに未対応環境への代替コンテンツ)
</video>
</syntaxhighlight>
<!-- バージョンが古すぎます。
=== 対応フォーマット ===
{| class="wikitable"
! !!colspan="4" |動画ファイル !!colspan="2" |動画ファイル
|-
! !! Ogg !! MP3 !! WAVE !! AAC !! Ogg !! H.264
|-
| Mozilla Firefox 3.6 || ○ || - || ○ || - || ○ || -
|-
| Google Chrome 4 || ○ || ○ || - || ○ || ○ || ○
|-
| Safari 4 || - || ○ || ○ || ○ || - || ○
|-
| Opera 10.50 || ○ || - || ○ || - || ○ || -
|}
-->
== canvas要素 ==
{{Main|JavaScript/Canvas}}
=== 概要 ===
[[w:canvas要素|canvas要素]]はダイナミックなビットマップ(ベクター)画像を描画する。二次元コンピュータグラフィックスはCanvas APIにより実現され<ref>https://html.spec.whatwg.org/multipage/canvas.html#2dcontext </ref>、ハードウェアアクセラレーションされた二次元及び三次元コンピュータグラフィックスは[[w:WebGL|WebGL]]を用いて実現される。
;書式
<syntaxhighlight lang="html5">
<canvas id="canvas" width="320" height="240">
(ここに未対応環境への代替コンテンツ)
</canvas>
</syntaxhighlight>
[[JavaScript]]を使用するとcanvasに画像を描くことができる。
;挿入するJavaScriptコード例
<syntaxhighlight lang="javascript">
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillRect(100, 100, 200, 200);
</syntaxhighlight>
JavaScriptは下記のようにcanvas要素と組み合わせて使用できます。
;HTMLでのJavaScriptとcanvasの組み合わせの例
<syntaxhighlight lang="html5">
<!DOCTYPE html>
<html lang="ja">
<head>
<title>簡単なページ</title>
</head>
<body>
<canvas id="canvas" width="320" height="240">
</canvas>
<script>
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillRect(100, 100, 200, 200);
</script>
</body>
</html>
</syntaxhighlight>
なお、上記のコードは、実行するとブラウザ画面に青い長方形を描きます。
ctx.fillStyle = "rgb(0,0,200)";
では色指定を行っています。0〜255の範囲で赤・緑・青の色見をそれぞれ指定しています。
ctx.fillRect(100, 100, 200, 200);
の書式は、上記htmlコード例の設定なら、
ctx.fillRect(始点x座標, 始点y座標, 横幅, 縦幅);
です。(第3引数と第4引数は、終点の座標位置ではないので、混同しないように注意しましょう。)
=== 簡単な動画の例 ===
[TODO:この例では、setInterval()を使って render() を(進捗によらず)キックしていますが、requestAnimationFrame()を使って書き直すべきです]
アニメーション処理などをしたい場合、円や四角などの簡単な図形を動かすだけなら、JavaScriptと要素を連携させれば、ウェブブラウザで簡単な図形がアニメーションする動画を表示させられる。
詳しい解説は、たとえば[https://developer.mozilla.org/ja/docs/Web/API/Canvas_API/Tutorial/Basic_animations モジラ公式サイト"Basic animations" ] などにある。もしかしたらブラウザの種類によって挙動が変わるかもしれないので、実用の際には都度、実機で確認のこと。
下記のコード中にある<code>setInterval</code> の書式と内容は
setInterval(function, delay)
::function で指定した関数を delay ミリ秒ごとに繰り返し実行、
である。
;[https://plnkr.co/edit/mIHg6c4ay3DbpMHz?open=lib%2Findex.html 簡単なcanvasアニメ]:<syntaxhighlight lang="html5">
<!DOCTYPE html>
<html lang="ja">
<head>
<title>簡単なアニメーション</title>
</head>
<body>
<canvas id="canvas" width="600" height="500"></canvas>
<script>
let ctx = canvas.getContext("2d"),
count = 0;
setInterval(() => {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = `hsl(${360*count/255},100%,50%)`;
ctx.fillRect(count, count, 40 + count/2, 40 + count/2);
count++;
count %= 256;
}, 5);
</script>
</body>
</html>
</syntaxhighlight>
== ページ内がいくつかの文書に分割される場合 ==
=== header要素 ===
header要素はヘッダ(ページ上部に表示される部分)を書くために利用する。
=== footer要素 ===
footer要素はフッタ(ページ下部に表示される部分)を書くために利用する。
=== aside ===
余談やサイドバーなど、メインでない要素であることを示す。
=== main ===
main要素は、そのページの主要な要素であることを示す。
main要素により、ヘッダやフッタ、サイドバーなどと区別することができる。
== nav要素 ==
nav要素は、その項目が目次や索引であることを知らせる。
[[w:パンくずリスト|パンくずリスト]]を作るために用いることができる。
== HTML4対応ファイルを改修する場合 ==
HTML5で廃止された機能を使う場合(たとえば frameset などはhtml5で廃止された)、HTML4に準拠してHTMLファイルを書く場合があります。
このような場合にも、header要素やnav要素を使いたい場合、html4仕様と矛盾しないでhtml5を意識したコードを書く方法があります。
それは class 属性を利用してdiv要素で、
<syntaxhighlight lang="html4strict">
<div class="header">
</div><!-- /header -->
</syntaxhighlight>
のように書く方法です。
こうすることで、将来もし、html5のどんな要素に対応するかを説明できるので、集団作業では色々と便利です。
なお、<nowiki> <!-- --></nowiki> は非表示タグというもので、コメントを書くのに使われます。その非表示タグ内に書かれた文字はブラウザ画面には表示されません。
== 脚注 ==
<references />
== 外部リンク ==
* [https://html.spec.whatwg.org/multipage/ HTML Living Standard]
[[Category:HTML|5]]
{{stub}}
339q9huty4ga72of9zt3ydmxssutdz0
205831
205830
2022-07-25T07:41:53Z
Ef3
694
/* HTML4対応ファイルを改修する場合 */ HTML5以前のコードに、class="header" がない保証がない(というか偏在している)ので、この方法では解決にならない。またHTML5の追加要素があるとレンダリングが乱れるIEへの対策の色合いが濃く、IE亡き今となっては無意味なので削除。
wikitext
text/x-wiki
{{Wikipedia|HTML5}}
MediaWiki編集におけるhtml5対応については [[w:Help:ウィキテキストにおけるHTML]] を参照。
'''HTML5'''(エイチティーエムエルファイブ)とは、[[HTML]] 4.01の後継としてW3Cにより2014年に勧告された規格である<ref>2019年にW3CとWHATWGは「HTML Living StandardをHTMLとDOMの唯一の標準とし、W3Cは今後HTMLとDOMに関する標準の策定を行わない」旨合意したことを発表しました。この事により2021年6月現在のHTML5の(唯一の)標準は、HTML Living Standardのみとなっています。</ref>。
== HTML4.01からの変更点 ==
=== 構造の改善 ===
人が見てもコンピュータが見ても解読しやすい構造とするため、デザインに関係する部分はスタイルシートに記述し、要素や属性でデザインを指定することはしないという姿勢がより徹底された。そのためfont要素やcenter要素などいくつかの要素が廃止され、table要素におけるwidth属性やalign属性なども廃止された。HTML4.01で非推奨であったb要素やu要素などは復活している(非推奨が外された)が、要素の意味づけが変更されている。header, main, section, article, nav, aside, footerなどセクショニング要素が新たに追加され、文書構造をより簡潔に記述できるようになった。
=== マルチメディアへの対応 ===
マルチメディアへの対応も目的の一つであり、audio, video, embedなどの要素が追加された。
== HTML5ソースのサンプル ==
<syntaxhighlight lang="html5" line>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>簡単なページ</title>
</head>
<body>
<header>
<h1>簡単なページ</h1>
<nav>
<ul>
<li><a href="#">ホーム</a></li>
<li><a href="#">このサイトについて</a></li>
<li><a href="#">実績</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h2>はじめに</h2>
<p>このサイトは簡単なページのサンプルです。</p>
<article>
<h3>概要</h3>
<p>このページはサンプルです。</p>
</article>
</section>
<aside>
<h2>コラム</h2>
<p>コラムのような余談はASIDE要素に記述します。</p>
</aside>
</main>
</body>
</html>
</syntaxhighlight>
== DOCTYPE宣言について ==
[[w:文書型宣言|DOCTYPE宣言]]は、ドキュメントの種類を宣言します。HTML4では、この要素内で「!DOCTYPE html」以降にDTDによるスキーマが参照する仕様でした<ref>DTDでスキーマを参照しているのでHTML4はSGMLに基づいていると言えます。</ref>。しかしHTML5では <code><!DOCTYPE html></code> だけにするように決まりました<ref>DTDをDOCTYPE宣言に含まなくなったことにより、HTML5は最早SGMLではなくなり。この事は使用できる文字列実体参照の相違などに影響します。</ref>。
== audio要素とvideo要素 ==
audio要素はオーディオを再生、video要素は動画を再生する。embed要素やobject要素による埋め込みと異なり、この方法ではプラグインを介さずブラウザの機能で直接マルチメディアの再生を行うことが出来る。ただし、ブラウザにより対応フォーマットは異なる。
;audio要素とvideo要素のマークアップ例:<syntaxhighlight lang="html5">
<!-- audio要素の場合 -->
<audio autoplay controls>
<source src="example.ogg" type="audio/ogg">
<source src="example.mp3" type="audio/mp3">
(ここに未対応環境への代替コンテンツ)
</audio>
<!-- video要素の場合 -->
<video width="320" height="240" autoplay controls>
<source src="file.ogv" type="video/ogg">
<source src="file.mp4" type="video/mp4">
(ここに未対応環境への代替コンテンツ)
</video>
</syntaxhighlight>
<!-- バージョンが古すぎます。
=== 対応フォーマット ===
{| class="wikitable"
! !!colspan="4" |動画ファイル !!colspan="2" |動画ファイル
|-
! !! Ogg !! MP3 !! WAVE !! AAC !! Ogg !! H.264
|-
| Mozilla Firefox 3.6 || ○ || - || ○ || - || ○ || -
|-
| Google Chrome 4 || ○ || ○ || - || ○ || ○ || ○
|-
| Safari 4 || - || ○ || ○ || ○ || - || ○
|-
| Opera 10.50 || ○ || - || ○ || - || ○ || -
|}
-->
== canvas要素 ==
{{Main|JavaScript/Canvas}}
=== 概要 ===
[[w:canvas要素|canvas要素]]はダイナミックなビットマップ(ベクター)画像を描画する。二次元コンピュータグラフィックスはCanvas APIにより実現され<ref>https://html.spec.whatwg.org/multipage/canvas.html#2dcontext </ref>、ハードウェアアクセラレーションされた二次元及び三次元コンピュータグラフィックスは[[w:WebGL|WebGL]]を用いて実現される。
;書式
<syntaxhighlight lang="html5">
<canvas id="canvas" width="320" height="240">
(ここに未対応環境への代替コンテンツ)
</canvas>
</syntaxhighlight>
[[JavaScript]]を使用するとcanvasに画像を描くことができる。
;挿入するJavaScriptコード例
<syntaxhighlight lang="javascript">
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillRect(100, 100, 200, 200);
</syntaxhighlight>
JavaScriptは下記のようにcanvas要素と組み合わせて使用できます。
;HTMLでのJavaScriptとcanvasの組み合わせの例
<syntaxhighlight lang="html5">
<!DOCTYPE html>
<html lang="ja">
<head>
<title>簡単なページ</title>
</head>
<body>
<canvas id="canvas" width="320" height="240">
</canvas>
<script>
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillRect(100, 100, 200, 200);
</script>
</body>
</html>
</syntaxhighlight>
なお、上記のコードは、実行するとブラウザ画面に青い長方形を描きます。
ctx.fillStyle = "rgb(0,0,200)";
では色指定を行っています。0〜255の範囲で赤・緑・青の色見をそれぞれ指定しています。
ctx.fillRect(100, 100, 200, 200);
の書式は、上記htmlコード例の設定なら、
ctx.fillRect(始点x座標, 始点y座標, 横幅, 縦幅);
です。(第3引数と第4引数は、終点の座標位置ではないので、混同しないように注意しましょう。)
=== 簡単な動画の例 ===
[TODO:この例では、setInterval()を使って render() を(進捗によらず)キックしていますが、requestAnimationFrame()を使って書き直すべきです]
アニメーション処理などをしたい場合、円や四角などの簡単な図形を動かすだけなら、JavaScriptと要素を連携させれば、ウェブブラウザで簡単な図形がアニメーションする動画を表示させられる。
詳しい解説は、たとえば[https://developer.mozilla.org/ja/docs/Web/API/Canvas_API/Tutorial/Basic_animations モジラ公式サイト"Basic animations" ] などにある。もしかしたらブラウザの種類によって挙動が変わるかもしれないので、実用の際には都度、実機で確認のこと。
下記のコード中にある<code>setInterval</code> の書式と内容は
setInterval(function, delay)
::function で指定した関数を delay ミリ秒ごとに繰り返し実行、
である。
;[https://plnkr.co/edit/mIHg6c4ay3DbpMHz?open=lib%2Findex.html 簡単なcanvasアニメ]:<syntaxhighlight lang="html5">
<!DOCTYPE html>
<html lang="ja">
<head>
<title>簡単なアニメーション</title>
</head>
<body>
<canvas id="canvas" width="600" height="500"></canvas>
<script>
let ctx = canvas.getContext("2d"),
count = 0;
setInterval(() => {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = `hsl(${360*count/255},100%,50%)`;
ctx.fillRect(count, count, 40 + count/2, 40 + count/2);
count++;
count %= 256;
}, 5);
</script>
</body>
</html>
</syntaxhighlight>
== ページ内がいくつかの文書に分割される場合 ==
=== header要素 ===
header要素はヘッダ(ページ上部に表示される部分)を書くために利用する。
=== footer要素 ===
footer要素はフッタ(ページ下部に表示される部分)を書くために利用する。
=== aside ===
余談やサイドバーなど、メインでない要素であることを示す。
=== main ===
main要素は、そのページの主要な要素であることを示す。
main要素により、ヘッダやフッタ、サイドバーなどと区別することができる。
== nav要素 ==
nav要素は、その項目が目次や索引であることを知らせる。
[[w:パンくずリスト|パンくずリスト]]を作るために用いることができる。
== 脚注 ==
<references />
== 外部リンク ==
* [https://html.spec.whatwg.org/multipage/ HTML Living Standard]
[[Category:HTML|5]]
{{stub}}
h18qhu0n8zt2j2pkoxjalvtj3q86sx7
学習方法/高校受験/英語
0
19527
205839
205779
2022-07-25T11:53:19Z
Honooo
14373
/* 発音 */
wikitext
text/x-wiki
{{Notice|'''{{PAGENAME}}'''では、中学校英語高校受験対策の学習方法について解説します。独自研究や中立性を欠いた文章が含まれる場合があります。ご了承ください。}}
==高校受験に向けた英単語学習==
英作文をはじめ、基本的に英語のスペルは正しく書くべきだろう。もちろん試験ではスペル間違いはそれなりに減点、あるいは不可になる。
英単語のスペルを覚えるいい方法、効果的な方法があればよいが、それぞれの学習者の工夫も必要だと思うが、一般的にもさまざまな主張やアドバイスがある。
『進研ゼミ 高校入試情報サイト』では、中学校の英単語学習として、意味や用法を覚え、スペルも書いて練習しようと勧めている<ref name=":0">[https://czemi.benesse.ne.jp/open/nyushi/study/1367896_13980.html]2022年4月25日に確認</ref>。
英単語書き取り練習は漢字練習と同じようなものでしょう。まず中学校必須単語から、一単語あたり5~10回書いて覚えたい。
英語学習では英単語をそれなりの数覚えているのが有効、というのは、多くの人の主張するところで、中学生は中学生として覚えているのが妥当で必要な単語を、意味、スペル、そして出来れば品詞もしっかり覚えていくといいですよね。
しかし単語を覚えただけで、英語の学習バッチリとはならないだろうし、他にも発音や熟語、様々な用法を考慮した文作成や解釈、英語学習の要素は色々ありますよね。
しかし前編集者の推奨はあくまで単語書きとり練習中心、その過程でCD音声や例文読解を取り込めば、総合的な学習になるだろう、という主張<ref name=":0" />。
しかし一方で、書き取り練習は、英単語を覚えるための効果的な学習法ではない、という主張と、それを支持する論文もある<ref>[https://www.jstage.jst.go.jp/article/cogpsy/2005/0/2005_0_104/_article/-char/ja/ 見崎研志, & 仲真紀子. (2005). 記憶促進における反復書記の有効性に関する検討. ''日本認知心理学会発表論文集'', ''2005''(0), 104-104.]</ref><ref>[https://www.jstage.jst.go.jp/article/cogpsy/2006/0/2006_0_171/_article/-char/ja/ 見崎研志, & 仲真紀子. (2006). 反復書記学習が記憶に及ぼす影響. ''日本認知心理学会発表論文集'', ''2006''(0), 171-171.]</ref>。
その場合は、こういうやり方がいいだろう。まず、英単語を見てその意味を思い浮かべる。思い浮かべた意味と真の意味が違っていたら、真の意味を覚えて次の単語に移る。これを覚えるまで何回か繰り返す。こういう学習法が最適だという主張もあります。
また、最近は英単語を覚えるためのスマホアプリなどが登場している。これらを活用することも有効な手段であろう。
実は世の中学習法については諸説紛々で、いろいろな方法を語る人物がいるから、学習者の自主的な判断、選択、発想が必要になるだろう。いろいろ試して自分自身で学習法を見出すことも重要だし、他者の意見を取り入れるにしても、種々の方法を併用して、学習法、勉強とは何かという事を発展的に考えていくことが大切だと思います。
単語学習の方法の視点として、学習するなら覚えるなら、重要度の高い単語から覚えていきたい、そういう考えがありますよね。
もちろん長文や、読解問題では、結局それほど重要だとみなされない単語が使われることも多いので、この視点がどれほど的を射ているかも一考の余地がある。
しかし高校入試の試験問題では、あまり馴染みのない単語には注釈がついている場合が多いので、学習重要語、記憶優先順位というのはやっぱりあると思います。
ただ大筋では、中学校重要単語、高校重要単語と、段階を示す事が出来るでしょうが、実際の試験問題でその分類が徹底的に守られるわけではないでしょう。例えば disappoint「がっかりする」や opinion「意見」などは一般的に、高校 2~3年で学習する単語だと見なされてれているようですが、事実上高校入試で使われている。とはいえほとんどの場合は中学生では難しすぎる単語として、注釈、解説はあるでしょう。
ところで前編集者はやたら中学範囲と高校範囲の分別にこだわるけど、そんなの最初っからあいまいなものでね。結局学校での学習内容なんて、学校により、クラスにより、それぞれ違うもので、あるクラスで学習したことが別のクラスでは学習しない、ある中学課程の本に書かれていることがあるクラスでは学習しない、あるいはその逆、そんなことはしょっちゅうだし、あって当たり前だよ。
そういう差異やあいまいさ、むらを踏まえた上で、統一の試験問題、選考方針で入学者を選ぼうというのが高校入試なんだよね。その差異や違いについていちいち理屈を言って、不平を言って議論するなんて、愚論の極みだろう。
しかもそうやって選考した結果が、絶対の人間判断基準でもない。入試に受かるのも人生なら、落ちるのも人生だよ。
さて、英単語学習の話に戻りますが、例えば中学校向けあるいは高校受験対策向けの英単語集で勉強する道もありますよね。
前編集者の推奨では、この手の単語集の学習では前半部分は飛ばして、と、いうのは、多くの初歩的すぎる単語は別の機会で学習している可能性が高いから、中間の単語から学習するのがいいようですね。そして最後まで学習したら最初に戻る…。あるいは前半部分はもうやらないで、より次の段階の、例えば高校で学習するような単語の勉強に向かうのもいいようです。
==受験勉強の学習範囲==
前項でも書いたように、中学範囲、高校範囲と区別して、その違いにこだわることはあまり意味がないし、その区別も事実上あいまいだ。特に学習すべき単語については、明確に中学単語、高校単語と区別することは、ごく基本的な単語以外、はっきりしない、おおざっぱな物になるだろう。
公立高校の入学試験は、一般的に標準的、基本的な出題が多いので、英単語に関してもそんな難しい単語を使わず、学校教科書の範囲の単語が使用されると思われる。
近年は中学校英語で扱う単語数が増加しているようだ。しかし、基本的には学校で習う単語をよく理解して覚えておくのを現編集者は推奨するが、むしろ少し背伸びして手を伸ばして、高校1年向けの参考書(3000語程度)を学習するのも良いのではないか、という意見もある。
単語集は、高校受験用の単語集はもちろん中学校範囲の単語を扱っていますが、やはり依然として、高校初等の単語集にも手を出すことを勧める意見もある。
ただ県立・都立などの公立高校やごく普通の私立高校では、そんな難度の高い英単語は出てこないでしょう。国立大付属高校の試験でも、それほど英単語難度は高くないようだ。だから多少難易度の高い単語を使用するのは、私立の難易高入試でしょうね。
現編集者は、中学校時の学習は、中学校の範囲をじっくり良く理解すればそれで十分だと考えるが、いやそうではない、ある程度高校範囲を先行したほうが良いという主張も根強くある。ただその場合でも、例えば英単語において、高校3年くらいをターゲットにした難関大学受験用英単語を覚える必要はなく、せいぜい高校初歩、最基本英単語の理解で十分だろう。
前編集者は頑なに、英語の学校教科書と中学用単語集だけではやや受験対策として不足だと主張するが、本当だろうか? 現編集者は、中学生は高校受験も含めて、中学校の学習をしっかりすれば対策として十分だと考える。
と、言うか、それが十分なのに不合格にするような高校、行かなくてもいいのでは?
==難関私立高校==
……とは言え、難関私立高校入試では、英語試験問題としてかなりの難しい出題があるだろう。ある程度成績のいい子はそういう高校に行ってみたい、受験したいと思うだろうし、それは自然な希望だろう。
使用される単語、熟語も、かなり難しい言葉が使われる場合もある。
ただ現編集者は基本的に、優秀な人間の集まりとか、エリートの集まりとか、その辺の存在には全く興味がないので、この問題についてはほぼ何も知らないし語ることもない。だから、前編集をそのまま継承しつつ、幾つかの指摘をしておく。
まず、やはり使われる英単語の難度として、高いものになるだろうから、高校初等の単語集の学習は有用。
しかし、仮にその学習をするにした所で、高校初等重要語3000語を覚えればもう十分だと考えられる。
高校英単語4500語は覚える必要はないだろう。やはりある程度難易度の高い単語には解説がつく。
単語の他に、私立難易高では英作文の出題が目立つ。そのためには少しハードルを下げて、高校1800語をしっかり学習するとよいだろうという指摘がある。
しかしせっかく英作文をするなら、英米人が読んでも妥当な、自然な文章が書けると当然望ましいが、やはり初学者や中学生、ネイティブでもない日本人がいきなりそんな奇麗な文を書けるわけではないので、ある程度許容できると見なされれば、試験ではそこそこ点数になる。
基本的に高校入試とは、中学の学習に関する試験なので、まず中学校の課程をきちんと身に着けて理解することが重要だが、私立の難易高の場合は、少しそれより背伸びした学習も必要かもしれない。
== 文法 ==
===まず…===
中学校で学習する英文法は、我々の英語理解の基本になるものだが、しかし絶対的なものではないだろう。高校では高校で、英文法のアップデートがなされるし、そして高校を卒業した後でも、何度も何度も英文法と言語文法のアップデートはなされていくだろう。
しかし我々は小学校でさらっと英語を知った後、中学校で最初に割と深く英文法を学習することになる。これは受験対策でもそうでなくても、よく理解しておきたい。受験勉強として取り組むなら、受験標準問題集による演習でもよいし、参考書類での理解を主軸にした学習でも良いだろう。
このページは高校受験対策がテーマだから、問題集での演習を勧める人が多いし、もちろんそれはそれで有用だが、現編集者はむしろ、各種参考書類での理解と読解を主体にした学習も勧める。
と、いうのは、結局勉強というのは、他者の発する質問や問題に答えることではなく、物事を知り理解することだからだ。そして物事を良く理解して知っているのなら、大抵の問題や質問にはそこそこ解答できる。
===古い参考書===
古い本にももちろん内容はあるが、高校受験勉強をするなら、毎年最新の情報と教材をもとに学習するのが一番望ましいだろう。
===私立高受験===
文法事項に関して、中学校で学習する内容というのはある程度定められているが、そこから逸脱した、難易度の高い構文や文章が出題されると、解答も困るかもしれない。一般的には私立高入試でも、そんな文法的に扱いが難しい英文は使われないだろう。英語の構成や構文、文法事項の参考資料として、受験用の発展的な参考書を学習しておくのもいいだろう。
;中学生だけど高校参考書を先行して読んじゃうという勉強。
何度も書くがあまり背伸びしたり無理したり、また自分があまり凄くて賢い人間だと思い込むのは多々問題がある。特に中学校英語文法に関しては、高校学習に手を出すのはあまりメリットがないという指摘もある。最近では中学校で学習する文法事項が、1990年代より高度に、充実しているという。前編集者は仮定法や無生物主語の解説を例として挙げている。
;英検準2級
英検準2級程度の知識があると何かと良いという指摘がある。(仮定法ではなく一般の)過去完了や未来完了などちょっと凝った時制やアスペクトを扱う。ちなみに参考までに、現編集者が最近読んだ文法の本には、英語には2種類の時制しか無いという。それは現在時制と過去時制。より厳密には過去時制と非過去時制。Will は発話時の現在において未来をイメージしているから現在時制だという。そして時制とは違うアスペクト(相)という概念を指摘する。英語には完了と進行の2種類のアスペクトが見られると書いてあったよ。
しかし英検準2級の一般の参考書は文法解説はあまり充実していない。文法を知りたければやはり受験用参考書という事になるか。英検2級はさらに難しく、高校3年間の範囲なので、中学生は考慮に入れる必要はないだろう。
例えば仮定法過去完了も、一応中学校で学習するが、ちょっと面倒な文章ではある。ただ割と簡単に割り切ると、仮定法過去は想像と仮定の現在を示しているし、仮定法過去完了は想像と仮定の過去を示している。
== 発音 ==
発音に関しては、教科書、参考書に掲載されている発音記号、辞書にはある程度発音記号に関する解説がある、そして各種音声教材、などを参考にすることになる。
言葉は書かれた文章の前に、会話として、音として使う物だから、発音は重要だし、リスニングやスピーキングという教科、課題もある。
受験対策としては、発音は最重要課題とはならないかもしれないが、やはり言葉の音としての側面を知るのは必要な事だろう。
== リスニング ==
都立共通問題英語ではリスニング問題が出題されます。おそらく他県でもリスニング問題は出題されるはずです。
リスニング問題の対策について、リスニング問題には、やはり、日常的に英語教材を聞くというのが一番効果的です。参考書付属のリスニング対策音声を聞くなどして対策しましょう。
YouTubeなどで検索すれば、実際に話されている生の英語をいくらでも聞くことができますが、しかし中学生では語彙や文法の面で、いきなりネイティブの英語を聞き取るのは難しいと思います。もちろん、英語力にとても自身のある人はチャレンジしても構いませんが、しかし高校レベルの単語すら習得できていない中学生の多くにはYouTubeなどは非実用的です。
まず、高校レベルのリスニング教材を習得してからでないと、YouTubeなどに深入りしても、時間の無駄になります。
中学レベルでは、せいぜい、YouTubeの英語動画で英会話の雰囲気を掴んだり、実際の英会話のスピードを知るための参考としてYouTubeなどを視聴してみるぐらいが関の山でしょうか。
なお、前編集で、発音の教育が日本では軽視されてきたという主張があったのですが、間違いです。
CDどころかカセットテープすらも無かった明治や大正の時代、その代わりに国定教科書などで長々と発音の説明しています。「近代図書デジタルアーカイブ」という公共サイトに戦前の教科書があるので、それが証拠です(中高生の人は読みにいく必要ありません)。
ともかく、最近の動向として、リスニングも重視されるようになってきています。
なので、バランスよく勉強しましょう。もちろん、リスニングばかりを勉強して、書き取りも英作文もできないのでは本末転倒で、それはそれで困りますし、海外での実用性も乏しいでしょう。海外でも英作文や読み書きは必要なはずです。
なので、高校受験英語の勉強では、要するに普通に英単語の勉強などと併行して、リスニング教材なども勉強すればいいだけです。
== スピーキング ==
都立高入試では、2023年度からスピーキングテストが導入されます。おそらく、他県でもスピーキングテストが導入されるようになるのではないでしょうか。
== シャドーイング ==
シャドーイングとは、英語を「聞こえたままに」発音する練習方法です。英語の音についての理解が深まるので、リスニングやスピーキング対策に適しています。英文は何でもいいので、手頃なリスニング問題の音声からシャドーイングしてみましょう。また、慣れてきたら英語の曲をシャドーイングしてみるというのもいいでしょう。受験勉強の息抜きにもなりますし、楽しみながら学ぶというのも大切です。
== 英検 ==
英検を取っておくと高校受験において有利になる可能性があります。
東京都の場合、英検3級以上を取っておくと、私立併願や推薦で内申点を加算されるところが多いです。加算される点数は1点の場合が多いですが、加算方法や加算基準は高校により異なるので、公式HPや学校見学などで事前に確認しておきましょう。
英検3級以上は英語で面接官とのインタビューがあるので、英検を取得する場合、その対策が必要になります。
都立高一般入試の場合は英検取得が受験に有利になることはありません。
しかし、推薦の場合は都立私立どちらとも、英検はアピールポイントになるでしょう。
結果的に、英検を入試で使わなかったとしても、英検取得は英語学習のモチベーションになりますし、今の自分にどのくらいの英語力があるか分かったり、今後の英語の学習の指針になったりするので、余裕があれば受験したほうがいいでしょう。
なお、かつて俗に「英検3級が中学卒業レベル、標準的な高校受験レベル」みたいに言われていましたが、あくまで大まかな目安にすぎず(それもかなり大まか)、実際には出題傾向の違いもあり、英検と高校受験では単純には換算できません。なお近年、中学英語の教育範囲が変わり、今まで高校レベルで教えていた文法の一部(たとえば仮定法など)が中学に前倒しになったので、もしかしたら英検3級では高校受験対策としては不適かもしれません。(英検準2級程度のほうが文法的には近いのかもしれません。)
ともかく、一般入試を受けるなら、英検よりもまずは高校受験そのものの対策をするのが優先事項です。英検の対策ばかりして肝心の高校受験英語の勉強をしなければ、一般入試での高校受験英語の成績は当然ながら悪化します。なので、志望校への推薦合格などが確実で無い限りは、あくまで英検対策は補助にするのが安全でしょう。
[[Category:中学校教育|がくしゅうほうほうこうこうじゅけんえいご]]
[[Category:学習方法|がくしゅうほうほうこうこうじゅけんえいご]]
5m50jk73i4n0bjj3t8zq0iwk05s7m2z
高等学校国語総合/土佐日記
0
19594
205825
195123
2022-07-25T07:15:25Z
173.68.62.151
/* 作品解説 */ 誤字
wikitext
text/x-wiki
== 作品解説 ==
『土佐日記』(とさにっき)とは、'''紀貫之'''(きの つらゆき)によって平安時代に書かれた日記。
この時代、平仮名(ひらがな)や万葉仮名などの仮名(かな)は女が使うものとされていたが、作者の紀貫之は男だが、女のふりをして『土佐日記』を書いた。
日記の内容は'''私的'''な感想などであり、べつに公的な報告・記録などでは無い。
『土佐日記』は日本初の仮名文日記である。
紀貫之は公務で、土佐(とさ、現在の高知県)に 地方官として、国司(こくし)として 赴任(ふにん)しており、土佐守(とさのかみ)としての仕事をしていた。その任が終わり、その帰り道での旅の、五十五日間の日記である。
この時代の公文書などは漢文で書かれており、男も漢文を使うものとされていた。そして日記は、男が、公務などについての、その日の記録を、漢文で書いたのが日記だとされていた。
しかし、土佐日記では、その慣例をやぶり、ひらがなで、著者が女を装い、私的な感情を書いた。このように日記で私的な感情を表現するのは、当時としては異例である。
この『土佐日記』によって、私的な日記によって文学的な表現活動をするという文化が起こり、のちの時代の日記文学および女流文学に、大きな影響を与えた。そして今で言う「日記文学」というようなジャンルが、土佐日記によって起こり始めた。
(『土佐日記』はタイトルには「日記」とつくが、しかし現代の観点で見れば、『土佐日記』は後日に日記風の文体で書いた紀行文であろう。しかし、ふつう古典文学の『土佐日記』や『蜻蛉日記』(かげろうにっき)、『和泉式部日記』(いずみしきぶにっき)、『紫式部日記』(むらさきしきぶにっき)、『更級日記』(さらしなにっき)など、古典での「○○日記」などは、日記文学として扱うのが普通である。)
:※ 高校や大学入試での時点では、『土佐日記』の文学ジャンルは「日記」「日記文学」としておいても、問題ないだろう。
*各章の重要度
とくに冒頭の「'''門出'''」(かどで)が重要である。
「'''忘れ貝'''」と「'''帰京'''」は、その次ぐらいに重要である。とりあえず読者は、順番どおりに読めば、問題ないだろう。
== 門出(かどで) ==
=== 一 ===
著者の紀貫之は男だが、女のふりをして冒頭文を書いた。船旅になるが、まだ初日の12月21日は船に乗ってない。
* 大意
女である私も日記を書いてみよう。
ある人(紀貫之)が国司の任期を終え、後任の者への引継ぎも終わり、ある人(紀貫之)は帰りの旅立ちのために土佐の官舎を発った日が12月21日の夜だった。そして。ある人は船着場へ移り、見送りの人たちによる送別のため、皆で大騒ぎをしているうちに夜が更けた。
(まだ船には乗ってない。)
* 本文/現代語訳
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
'''男もすなる日記'''(にき)といふ(イウ)ものを、'''女もしてみむ'''(ミン)とて、'''するなり'''。
それの年の十二月(しはす、シワス)の二十日余り一日(ひとひ)の日の'''戌(いぬ)の刻(とき)'''に、門出す。そのよし、いささかに物に書きつく。
'''ある人'''、県(あがた)の四年(よとせ)五年(いつとせ)果てて、例の事(こと)どもみなし終へて(オエテ)、解由(げゆ)など取りて、住む館(たち)より出でて、船に乗るべき所へ渡る。かれこれ、知る知らぬ、送りす。年ごろ、よくくらべつる人々なむ(ナン)、別れ難く思ひて(オモイテ)、'''日しきりに'''とかくしつつ、'''ののしる'''うちに、夜更けぬ。
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
'''男もするという日記'''というものを、'''女も書いてみよう'''として'''書くのである'''。
ある年の十二月の二十一日の午後八時頃に、(土佐から)出発する。その時の様子を、少しばかり、もの(=紙)に書き付ける。
ある人が(='''紀貫之''')、国司の(任期の)4年・5年間を終えて、(国司交代などの)通例の事務なども終えて、解由状(げゆじょう)などを(新任者から紀貫之が)受け取って、住んでいた官舎(かんしゃ)から(紀貫之は)出て、(紀貫之は)船に乗る予定の所へ移る。
(見送りの人は)あの人この人、知っている人知らない人、(などが、私を)見送ってくれる。
長年、親しく交際してきた人が、ことさら別れがつらく思って、'''一日中'''、あれこれと世話をして、'''大騒ぎ'''しているうちに、夜が更けてしまった。
|}
----
* 語句
:・'''男もすなる日記'''- この時代、日記は』男が書くものであった。「すなる」の「なる」は、伝聞の助動詞「なり」の連体形。
:・'''女もしてみむ''' - 作者は本当は男だが、女のふりをしている。
:・するなり - ここでの「なり」は断定の助動詞。
※ '''男もすなる日記(にき)といふものを、女もしてみむとて、するなり'''。 - とても有名な冒頭文なので、読者は、そのまま覚えてしまっても良い。
:・'''戌(いぬ)の刻(とき)''' - 午後8時ごろ。当時の旅立ちや旅からの帰宅は、人目を避けるべきとされており、そのため夜に行うのが通常だった。
:・'''ある人''' - 紀貫之。
:・'''日しきりに''' - 一日中。
:・'''ののしる''' - 大騒ぎする。現代語とは違っており、悪い意味とは限らない。
単語
「'''わたる'''」(「住む館(たち)より出でて、船に乗るべき所へ渡る」の文):「わたる」(渡る)はここでは「行く」の意味。古語の「わたる」には、「行く」のほかにも「時間をすごす」や「生計を立てる」、(草花や霧などが)「一面に広がる」など、さまざまな意味がある。
「'''よし'''」(「よし」の漢字は「由」): 多義語であり、1.方法、 2.由緒、 3.様子・旨、 といった意味がある。この場面では旨の意味。もとの文の意味は「その旨を、少しばかりものに書きつける。」の意味。
なお関連語として、形容詞「よしなし」は、「理由がない」「方法がない」、「つまらない」という意味である。
「果てて」(はてて): ここでは、「果てて」とは「終わって」の意味。なお、単語集で調べるときは「果つ」(はつ)で調べる。
※ なお、枕草子の「春はあけぼの」の「日入り果てて、風の音、草の音など、はた言うべきにもあらず」の果てての意味は、「すっかり」の意味。上記の「終わる」とは、やや意味が違う。つまり、「日入り果てて」は「日がすっかり沈んでしまって」という意味。
※ 「果つ」を掲載している単語集が少ない。三省堂『古文単語300PLUS』なら掲載されている。
* 古典常識
:・この時代、平仮名は女が使う文字だった。
:・この時代、日記は、男が公的な記録などを記録するものだった。
:・この時代、時刻の表記には、十二支(じゅうにし)を使う。十二支とは「えと」の「ね・うし・とら・う・たつ・み・うま・ひつじ・さる・とり・いぬ・い」のこと。
* 語釈
:・解由(げゆ) - 官吏の交代のときの書類。前任の官吏に過失が無いことを証明する書類。後任の管理が発行する。前任の官吏が受け取る。前任者が帰京後、解由状を役所に提出する。
:・住む館(たち) - この日記では、国司の官舎のこと。高知県にあった。
:・ -
----
=== 二 ===
*大意
22日、船旅の安全を祈る儀式をする。この日、「藤原のときざね」(人名?)が送別の宴(うたげ)を開いてくれた。
23日、「八木のやすのり」が餞別をくれた。
この人たちのおかげで人情の厚さを思い知らさた。いっぽう、関係が深かったのに送別も餞別もしない人たちの人情の薄さを思い知らされた。
24日、国分寺の僧侶も送別をしてくれた。宴で、身分に関わらず酔い、子供までも酔いしれた。
*本文/現代語訳
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
二十二日(はつかあまりふつか)に、和泉(いづみ、イズミ)の国までと、平らかに願(ぐわん、ガン)立つ。藤原(ふぢはら、フジワラ)のときざね、船路(ふなぢ、フナジ)なれど、'''馬(むま)のはなむけ'''す。上中下(かみなかしも)、'''酔(ゑ)ひ飽きて'''(エイアキテ)、いと'''あやしく'''、潮海(しほうみ、シオウミ)のほとりにて、'''あざれ合へり'''(アザレアエリ)。
二十三日(はつかあまりみか)。八木(やぎ)のやすのりといふ人あり。この人、国に必ずしも言ひ(いい)使ふ(つかう)者にもあらざなり。これぞ、たがはしきやうにて、馬(むま)のはなむけしたる。守柄(かみがら)にやあらむ、国人(くにひと)の心の常として「今は。」とて見えざなるを、心ある者(もの)は、恥ぢずきになむ来(き)ける。これは、物によりて褒むる(ひむる)にしもあらず。
二十四日(はつかあまりよか)。講師(かうじ)、馬(むま)のはなむけしに出でませり。ありとある上下(かみしも)、童(わらは、ワラワ)まで酔ひ痴しれて(しれて)、一文字(いちもんじ)を'''だに'''知らぬ者(もの)、'''しが足'''は'''十文字(ともじ、じゅうもんじ)に踏みてぞ遊ぶ'''。
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
二十二日に、和泉(いづみ)の国まで無事であるようにと、祈願する。藤原のときざねが、船旅だけれど、'''馬のはなむけ'''(=送別の宴)をする。身分の高い者も低い者も、(皆、)酔っ払って、'''不思議なことに'''、潮海のそばで、'''ふざけあっている'''。
二十三日。「八木(やぎ)のやすのり」という人がいる。この人は国司の役所で、必ずしも召し使っている者ではないようだ。(なんと、)この人が(=八木)、立派なようすで、餞別(せんべつ)をしてくれた。(この出来事の理由は、)国司(=紀貫之)の人柄(の良さ)であろうか。(そのとおり、紀貫之の人柄のおかげである。)
任国の人の人情の常としては、「今は(関係ない)。」と思って見送りに来ないようだが、(しかし、八木のように)人情や道理をわきまえている者は人目を気にせず、やってくることだよ。これは、(けっして)贈り物を貰ったから褒めるのではない。
二十四日。国分寺の僧侶が、餞別をしに、おいでになった。そこに居合わせた人々は、身分の高い者・低い者だけでなく、子供までも酔っぱらって、(漢字の)「一」の文字'''さえ'''知らない(無学の)者が、(ふらついて、)'''その足を'''「十」の字に踏んで遊んでいる。
|}
----
*語句
:・'''馬(むま)の はなむけ''' - 送別の宴(うたげ)。旅立つ人への餞別(せんべつ)。旅立ちのときに、'''馬の鼻'''を旅先に'''向け'''て安全をいのる儀式が、語の元になっている。
::船旅なので馬には乗らないが、送別の宴をしてもらったので、「馬のはなむけ」だという言葉遊び。
:・酔(ゑ)ひ飽きて - 意味は「すっかり酔っ払って」。
:・'''あやしく''' - 不思議なことに。この文では、次の文節の「あざれ」の言葉遊びに掛かっているので、作者が「不思議だ」と冗談を言っている。
:・'''あざれ合へり''' - ふざけあっている。「戯る」(あざる)の意味は「ふざける」。
::「あざる」には他の意味で「(魚などが)腐る」という意味の「鯘る」(あざる、「魚」偏に「委」の字。)もあり、海なので塩で魚は腐らないはずだが、ふざけあっているので「あざる」という言葉遊びをして、掛けている。
:・しが足 - その足は。「しが」には諸説ある。そのうち、「し」=代名詞、「が」=格助詞(主格)、という説が学校教科書で有力。
:・'''一文字(いちもんじ)をだに''' - 漢字の「一」の文字さえ。「・・・だに」の意味は「・・・さえ」。「だに」は副助詞。おそらく「一文字」とは漢文の教養の初歩の例えか。
*語句
:・和泉(いづみ)の国 - 大阪府の南部。
:・藤原(ふづはら)のときざね - 伝未詳。土佐の国の役人か。
:・八木(やぎ)のやすのり - 伝未詳。
:・守柄(かみがら) - 国司の人柄や実績。
:・ -
:・ -
=== 品詞分解 ===
==== 一 ====
男 '''も'''('''係助詞''') '''す'''('''サ変'''・終止) なる(助動詞・伝聞・連体) 日記 と(格助詞) いふ(四段・連体) もの を(格助詞)、女 も(係助) し て(接続助詞) み('''上一段'''・未然) む(助動詞・意志・終止) とて(格助)、 '''する'''('''サ変'''・連体) なり(助動・断定・終止)。
それ の(格助) 年 の(格助) 十二月 の(格助) 二十日余り一日 の(格助) 日 の(格助) 戌の刻 に(格助) 、 門出す('''サ変'''・終止。 '''そ'''('''代名詞''') の(格助) よし、いささかに('''ナリ・連用''') 物 に(格助) 書きつく(下二段・終止)。
'''ある'''('''連体詞''') 人、 県 の(格助) 四年五年 果て(下二段・連用) て(接助)、例 の(格助) 事ども みな(副詞) し終へ(下二段・連用) て(接続助詞)、解由 '''など'''('''副助詞''') 取り(四段・連用) て(接続助詞)、 住む(四段・連体) 館 '''より'''('''格助''') 出で(下二段・連用) て(接続助詞)、 船 に(格助) 乗る(四段・終止) '''べき'''(助動詞・'''当然'''・連体) 所 へ(格助) 渡る(四段・終止)。 かれこれ('''連語''')、 知る(四・連体) 知ら(四・未然) '''ぬ'''(助動詞「ず」・'''打消し'''・連体)、 送りす(サ変・終止)。 年ごろ、 よく('''ク活用'''・連用) くらべ(下二段・連用) つる(助動詞・'''完了'''・連体) 人々 なむ(係助詞)、 別れ難く(ク活用・連用) 思ひ(四段・連用) て(接続助詞)、日 しきりに(副詞) とかく(副詞) し(サ変・連用) '''つつ'''(接続助詞)、 ののしる(四段・連体) うち に(格助)、 夜 更け(下二段) ぬ(助動詞・完了・終止)。
==== 二 ====
二十二日(はつかあまりふつか) に(格助)、 和泉の国 まで(副助詞) と(格助詞)、 平らかに(ナリ・連用) 願 立つ(下二段・終止)。 藤原(ふぢはら、フジワラ)のときざね、 船路 なれ(助動詞・断定・已然) '''ど'''('''接続助詞''')、 馬(むま)のはなむけ す(サ変・終止)。 上中下(かみなかしも)、酔ひ飽き(四段・連用) て(接助)、いと(副) あやしく(シク・連用)、 潮海 の(格助) ほとり にて(格助)、 あざれ合へ(四段・已然) り(助動詞・完了・已然) 。
二十三日。 八木(やぎ)のやすのり と(格助) いふ(四段・連体) 人 あり(ラ変・終止) 。 こ(代名詞) の(格助) 人、 国 に(格助) 必ずしも(副詞) 言ひ使ふ(四段・連体) 者 に(助動詞・断定・連用) も(係り助詞) あら(ラ変・未然) ざ(助動・打消・体、音便) なり(助動・'''推量'''・終止)。 これ(代名詞) '''ぞ'''(係り助詞、'''係り''') 、たがはしき(シク・連体) やう に(助動・断定・用) て(接助)、 馬(むま)のはなむけ し('''サ変'''・連用) たる(助動・完了・連体、'''結び''')。 守柄(かみがら) に(助動・断定・連用) '''や'''(係助詞、'''係り''') あら('''補助動詞'''・ラ変・未然) む(助動・推量・連体、結び)、 国人(くにひと) の(格助) 心 の(格助) 常 と(格助) して(接助) 「今 は(係助詞)。」 とて(格助) 見え(下二段・未然) ざ(助動詞・打消し・連体、音便) なる(助動詞・'''推定'''・連体) を(格助) 、 心 '''ある'''('''ラ変'''・連体) 者 は(係り助詞) 、恥ぢ(紙二段・未然) ず(助動詞・打消し・連用) に(格助) なむ(係り助詞・係り) 来(カ変・連用) ける(助動詞・'''詠嘆'''・連体、結び)。 これ(代名詞) は(係り助詞)、 物 に(格助) より(四段・連用) て(接助) 褒むる(下二段・未然) に(助動詞・断定・連用) '''しも'''('''副助詞''') あら('''補助動詞'''・ラ変・未然) ず(助動詞・打消し・終止)。
二十四日(はつかあまりよか)。 講師(かうじ)、 馬(むま)のはなむけ し(サ変・連用) に(格助) 出で(下二・連用) ませ(補助尊敬・四段・已然) り(助動詞・完了・終止)。 あり(ラ変・連用) と(格助詞) ある(ラ変・連用) 上下(かみしも)、童(わらは、ワラワ) まで(副助詞) 酔ひ痴しれ(下二段・連用) て(接助) 、一文字(いちもんじ) を(格助) '''だに'''('''副助詞''') 知ら(四段・未然) ぬ(助動詞「ず」・打消し・連体) 者、しが足 は(係り助詞) 十文字 に(格助) 踏み て(接助) '''ぞ'''(係り助詞、'''係り''') 遊ぶ(四段・'''連体'''、'''結び''') 。
== 忘れ貝 ==
=== 一 ===
*大意
*本文/現代語訳
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
四日(よか)。楫取り(かぢとり)、「今日、風雲(かぜくも)の気色(けしき)はなはだ悪し(あし)。」と言ひて、船出ださず(ふねいださず)なりぬ。'''しかれども'''、'''ひねもすに'''波風立たず。この楫取りは、日も'''え測らぬ'''(はからぬ)かたゐなりけり。
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
四日。船頭が、「今日、風と雲の様子が、ひどく悪い。」と言って、船を出さずになった。であるけれど、'''一日中'''、波風が立たなかった。この船頭は天気も'''予測できない'''愚か者であったよ。
|}
----
*語句
:・'''しかれども''' - そうではあるけれど。逆接の接続詞。
:・'''ひねもすに''' - 一日中。
:・'''え測らぬ''' - 予測できない。「え・・・(打消し)」の意味は「・・・できない」。この末尾「ぬ」は打消の助動詞「ず」の連体形。「え・・・ず」で'''不可能'''を表す。「え」は副詞。
:・ -
*語句
:・楫取り(かぢとり) - 船頭。
:・気色(けしき) - 様子。
:・日(ひ)- ここでは天気・天候の意味。
:・かたゐ - おろかもの。ばかもの。役立たず。
:・ -
----
=== 二 ===
*大意
*本文/現代語訳
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
この泊(とまり)の浜には、'''くさぐさ'''の'''うるはしき'''貝・石など多かり。'''かかれば'''、ただ'''昔の人'''をのみ恋ひつつ、'''船なる人'''の詠(よ)める、
:寄する波うちも寄せなむ我(わ)が恋ふる人'''忘れ貝'''降りて拾はむ
と言へれば、'''ある人'''の耐へずして、船の心やりに詠める、
:忘れ貝拾ひしもせじ'''白玉'''(しらたま)を恋ふるをだにも形見と思はむ
となむ言へる。女子(おんなご)のためには、親幼くなりぬべし。「玉ならずもありけむを。」と、人言はむや。されども、「死じ子、顔よかりき。」と言ふやうもあり。
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
この泊(とまり)の浜には、'''いろいろ'''な'''美しい'''貝・石などが多くある。'''こうなので'''、ただ'''亡くなった人'''(紀貫之の娘)ばかりを恋しがって、船の中にいる人('''紀貫之の妻''')が歌を詠んだ、
:(船の中の人の歌:) 寄する波 うちも寄せなむ 我(わ)が恋ふる 人 '''忘れ貝''' 降りて拾はむ
:意味: 浜辺に打ち寄せる波よ、どうか忘れ貝を打ち寄せておくれ、私の恋しい人(死んだ娘を思うつらさ)を忘れてさせてくれる忘れ貝を。(忘れ貝を、浜に)降りて拾おう。
と言ったところ、ある人('''紀貫之''')がこらえられなくなって、船旅の気晴らしに詠んだ、
:(ある人の歌:) 忘れ貝 拾ひし(ヒロイシ)もせじ '''白玉'''(しらたま)を 恋ふるをだにも 形見と思はむ
:意味: 忘れ貝なんか、拾いもすまい。(あの子のことは忘れたくない。)せめて、白玉(のようにかわいかった'''亡き子''')を恋しく思う気持ちだけでも形見と思おう。
と言ったのだった。(亡くなった)女の子のためには、親は幼子のように(おろかに)なってしまうのにちがいない。「玉というほどでは、ないだろう。」と人は言うだろうか。けれども、「死んだ子は顔立ちが良かった。」と言うこともある。
|}
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
なほ同じ所に日を経ることを嘆きて、ある女の詠める歌、
:手をひてて 寒さも知らぬ 泉にぞ 汲む(くむ)とはなしに 日ごろ経にける
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
やはり、同じ場所で日を過ごすことを嘆いて、ある女の詠んだ歌、
:(ある女の歌:)
:意味: 手を漬けても、寒さを感じない泉、( = 和泉)、その和泉で水を汲むわけでもなく、(なすことも無く、何日も)日を過ごしてしまったよ。
|}
----
*語句
:・'''くさぐさ''' - いろいろの。さまざまな。
:・'''うるはしき''' - 美しい。きれい。形容詞「うるはし」の連用形。整った美しさのこと。
:・'''かかれば''' - 「かくあれば」の、つづまった形。
:・'''昔の人''' - 故人。亡くなった人。ここでは、紀貫之の娘のこと。娘は死んでいる。
:・ -
:・'''忘れ貝''' - これを拾うと恋しい思いを忘れることができるという。詳細は不明。 説は次の二つ。 1:二枚貝のうちの片方の貝。 2:アワビのような一枚貝。
:・'''白玉'''(しらたま) - 白い玉。真珠(しんじゅ)。この文では、'''亡くなった娘のたとえ'''。
*'''船なる人'''(船の中にいる人)が'''紀貫之の妻'''だと、なぜ分かるか?
この「忘れ貝」の章で「船なる人」と「ある人」との和歌のやり取りがあるが、他の章などの記述では「ある人」の正体が紀貫之だという場合が多く、そのため、この「忘れ貝」の章に登場する「ある人」も紀貫之だろうと考えられている。もっとも、あくまで現代の学者たちの仮説なので、もしかしたら妻と夫は逆かもしれないし、あるいは両方の和歌とも紀貫之の和歌かもしれない。
とりあえず読者の高校生は、作中での「船なる人」と「ある人」とは夫婦であって、そして、この夫婦は任地の土佐で娘を亡くしていることを理解すればよい。
=== 品詞分解 ===
== 帰京 ==
=== 一 ===
*大意
*本文/現代語訳
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
夜ふけて来れば、所々(ところどころ)も見えず。京に入り(いり)立ちてうれし。家に至りて、門(かど)に入るに、月明かければ(あかければ)、いとよくありさま見ゆ。聞きしよりもまして、言ふ効(かひ)なくぞ毀れ(こぼれ)破れたる。家に預けたりつる人の心も、荒れたるなりけり。中垣'''こそあれ'''、一つ家のやうなれば、望みて預かれるなり。'''さるは'''、'''便りごと'''に物も絶えず得させたり。今宵(こよひ、コヨイ)、「'''かかること'''。」と、声高(こわだか)にものも言はせず。いとは辛く(つらく)見ゆれど、'''心ざし'''はせむとす。
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
夜がふけてきたので、あちらこちらも見えない。京に入っていくので、うれしい。(私の)家に着いて、門に入ると、月があかるいので、とてもよく様子が見える。(うわさに)聞いていたよりもさらに、話にならないほど、(家が)壊れ痛んでいる。家(の管理)を預けていた(隣の家の)人の心も、すさんでいるのであったよ。(私の家と隣の家との間に)中垣こそあるけれど、一軒家のようなので(と言って)、(相手の隣家のほうから)望んで預かったのだ。(なのに、ひどい管理であったよ。)そうではあるが、'''ついで'''があるたびに(= 誰かが京に行くついでに隣家へ贈り物を届けさせた)、(土佐からの)贈り物を(送って、相手に)受け取らせた。(しかし、けっして)今夜は「こんな(='''荒れて、ひどい''')こと。」とは(家来などには)大声で言わせない。たいそう、(預かった人が)ひどいとは思うけど、'''お礼'''はしようと思う。
|}
----
* 語句
:・ -
:・中垣'''こそあれ''' - 中垣はあるけれども。「こそ・あれ」が係り結びになってる。
:・'''便りごと''' - 機会のあるたびに。ついでに。
:・心ざし - お礼。「志」(こころざし)とも書く。
読解
:・'''かかること''' - ここでの「かかること」とは、家が荒れて、ひどいありさまなこと。
* 単語
「'''たより'''」(頼り、便り):古語の「たより」は、多義語であり、「1.信頼できるもの 2.ついで・機会 3.音信・手紙」現代語と同じような意味の「信頼できるもの」というような用法もあるが、しかしこの場面では別の意味。この場面では、「機会」「ついで」の意味。
:※ 単語集では手紙の意味を解説しているものは少ないが、しかし源氏物語で「語らひつきにける女房のたよりに、御有様なども聞き伝ふるを」という文章がある。数研出版『解法古文単語350』に音信の意味が紹介されている。
「'''言う効(かい)なし'''」: ここでの「言う効なし」は「言う甲斐なし」のような意味で、「言いようがない」のような意味。
だが、江戸時代の本居宣長の随筆『玉勝間』では、「つまらない」「価値がない」のような意味で「言うかいなし」と使っている用法もある。『玉勝間』では「よきあしきをいはず、ひたぶらにふるきをまもるは、学問の道には、いふかひなきわざなり」とある。「良し悪しを言わず、ひたすら古い説を守るのは、学問の道としては、つまらないものである」のような意味。
----
=== 二 ===
*大意
荒れはてた庭に新しい小松が育ち始めている。出迎えの子供の様子を見て、土佐で無くなった娘を思い出し、自分の心を分かってくれる人とひそかに歌を交わした。
忘れがたいことが多く、とても日記には書き尽くすことは出来ない。ともかく、こんな紙は早く破り捨ててしまおう。
*本文/現代語訳
{| style="width:100%"
|valign=top style="width:40%;text-indent:0em"|
さて、池めいて窪まり(くぼまり)、水つける所あり。ほとりに松もありき。五年(いつとせ)六年(むとせ)のうちに、'''千年(ちとせ)や過ぎにけむ'''、'''片方'''(かたへ)はなくなりにけり。いま生ひたるぞ(おいたるぞ)交じれる。大方(おおかた)の'''みな'''荒れにたれば、「'''あはれ'''。」とぞ人々言ふ。思ひ出でぬ(いでぬ)ことなく、思ひ恋しきがうちに、この家にて生まれし女子(おむなご)の、もろともに帰らねば、'''いかがは悲しき'''。船人(ふなびと)も、皆(みな)、子たかりてののしる。かかるうちに、なほ悲しきに堪へずして、ひそかに'''心知れる人'''と言へりける歌、
:生まれしも(むまれしも)帰らぬものをわが宿に小松のあるを見るが悲しさ
とぞ言へる。なほ飽かずやあらむ、また、かくなむ。
:見し人の松の千年(ちとせ)に'''見ましかば遠く悲しき別れせまし'''や
忘れがたく、口惜しき(くちをしき)こと多かれど、'''え尽くさず'''。'''とまれかうまれ'''、'''疾く(とく)'''破りてむ(やりてむ)。
|valign=top style="width:10%;text-indent:1em"|
|valign=top style="width:45%;text-indent:1em"|
さて、池のようにくぼんで、水がたまっている所がある。そばに松もあった。(土佐に赴任してた)五年・六年の間に、(まるで)千年も過ぎてしまったのだろうか、(松の)'''半分'''は無くなっていた。(← 皮肉。松の寿命は千年と言われてた。)
新しく生えたのが混じっている。
だいたいが、'''すっかり'''荒れてしまっているので、「ああ(ひどい)。」と人々が言う。思い出さないことは無く(= つまり、思い出すことがある)、恋しく思うことの中でも、(とくに)この家で生まれた女の子(= 土佐で亡くした娘)が、土佐から一緒には帰らないので、どんなに悲しいことか。(=とても悲しい。)
(一緒に帰京した)乗船者は、みんな、子供が集まって大騒ぎしている。こうしているうちに、(やはり?、なおさら?、※ 訳に諸説あり)悲しいのに耐えられず、ひっそりと気心の知れた仲間(= '''紀貫之の妻か'''?)と言った歌、
:(歌:) 生まれしも 帰らぬものを わが宿に 小松のあるを 見るが悲しさ
:意味: (この家で)生まれた子も(土佐で死んだので)帰ってこないのに、我が家(の庭)に(新たに生えた)小さな松があるのを見ると、悲しいことよ。
と言った。
それでも/やはり(※ 訳に諸説あり)、満足できないのであろうか、またこのように(歌を詠んだ)。
:(歌:) 見し人の 松の千年に 見ましかば 遠く悲しき 別れせましや
:意味: 死んだあの子が、(もし)松の千年のように(生きながらえて、)(わが子を)見ることが出来たなら、'''遠く悲しい別れ( = 土佐での娘との死別)をしただろうか。いや、しなかっただろう。'''
忘れがたく、残念なことが多いけど、書きつくすことが出来ない。'''ともかく'''、(こんな日記は)'''すぐに'''破ってしまおう。
|}
----
*語句
:・'''千年(ちとせ)や過ぎにけむ''' -
:・'''あはれ''' - ああ(ひどい)。まあ(ひどい)。感動詞。
:・'''いかがは悲しき''' - 結びが連体形(「悲しき」)で、係り結びになっている。係り助詞に諸説あり。 1:「は」が係り助詞。 2:「いかが」が「いかにか」の略で「か」が係り助詞と言う説もある。 どちらにせよ、例外的な用法なので、このまま「いかがは悲しき」で覚えよう。
:・'''見ましかば 遠く悲しき 別れせましや''' - 「ましかば・・・まし」で'''反実仮想'''(はんじつ かそう)。「もし・・・だったら、そうであろうか。(いや、そうではない。)」
:・ -
:・'''え尽くさず''' - 「え・・・(打消し)」の意味は、・・・出来ない。ここでの意味は「書きつくすことが出来ない」
:'''とまれかうまれ''' - 「ともあれかくもあれ」の音便。ともかく。とにかく。
:・'''疾く(とく)'''破りてむ(やりてむ) - 早く破り捨ててしまおう。「とく」は形容詞「とし」の副詞的用法で連用形「とく」。 ※ 「とく」が、はたして形容詞か副詞かどちらなのかは、読者は気にしなくて良い。
* 語句
:・ -
:・ -
:・ -
* 関連事項
「もがな」: 土佐日記には、上記とは他の文章だが「いかで疾く(とく)京へもがな。」という文章がある。「どのようにかして、早く京都に帰りたいなあ。」という意味である。「もがな」は「したいなあ」「が欲しいなあ」の意味の終助詞である。
徒然草にも、「心あらむ友もがなと、都恋しうおぼゆれ。 」とあり、「情趣を解する友人がいたらなあ、と都が恋しく思われる。 」のように訳す。
また、「いかで」~「もがな」や「いかにも」~「もがな」のように、「もがな」は「いかで」などに呼応する。
『更級(さらしな)日記』に、「幼き人々を、いかにもいかにも、わがあらむ世に見置くこともがな。」とある。「幼い子供たちを、何とかして何とかして、自分が生きているうちに見届けておきたいものだなあ。」のような意味。
さて、百人一首に「名にしおはば 逢坂山の さねかづら 人に知られで くるよしもがな」という和歌がある(後撰和歌集)。この歌の後半部の「人に知られで くるよしもがな」も、「人に知られないで来る方法があればいいのになあ。」という意味である。
=== 品詞分解 ===
==== 一 ====
夜ふけて来れば、所々も見えず。京 に(格助) 入り立ち(四・用) て(接助) うれし(シク・終)。 家 に(格助) 至り(四・用) て(接助)、 門 に(格助) 入る(四・体) '''に'''('''接助''')、 月 明かけれ(ク・已然) ば(接助)、 いと(副詞) よく(ク・用) ありさま 見ゆ(下二段・終)。 聞き(四段・用) し(助動詞・過・体) より も(係助) まし(四・用) て(接助)、 言ふ効なく(ク・用) '''ぞ'''(係助、'''係り''') 毀れ(下二・用) 破れ(下二・用) たる(助動・完・連体、'''結び''')。 家 に(格助) 預け(下二・用) たり(助動・完了・用) つる(助動・完・体) 人 の(格助) 心 も(係助) 、 荒れ(下二・用) たる(助動・完・体) なり(助動・断定・用) けり(助動・詠嘆・終)。 中垣 '''こそ'''(係助、'''係り''') '''あれ'''(ラ変・'''已然'''、'''結び''')、一つ家 の(格助) '''やうなれ'''(助動・'''比況'''・已然) ば(接助)、望み(四・用) て(接助) 預かれ(四・已然) る(助動・完了・体) なり助動・断定・終)。 さるは(接続詞)、便りごと に(格助) 物 も(係助) '''絶えず'''(副詞) 得(下二段・未然) させ(助動・'''使役'''・用) たり(助動・完了・終止)。 今宵、「かかる(ラ変・体) こと。」 と(格助)、声高に(ナリ・用) もの も(係助) 言は(四・未) せ(助動・使役・未) ず(助動・打消し・終)。 いと(副詞) は(係助) つらく(ク・用) 見ゆれ(下二・已然) ど(接助)、心ざし は(係助) せ('''サ変'''・未然) '''む'''(助動・'''意志'''・終) と(格助) す(サ変・終止)。
==== 二 ====
さて(接続詞) 、池めい(四段・用、音便) て(接助) 窪まり(四段・用)、水つけ(四・已然) る(助動・存続・体) 所 あり(ラ変・終止)。 ほとり に(格助) 松 も(係助) あり(ラ変・用) き(助動・過・終)。 五年六年 の(格助) うち に(格助)、千年 '''や'''(係助、係り) 過ぎ(上二段・用) に(助動・完了・連用) '''けむ'''(助動・'''過去推量'''・連体)、かたへ は(係助) なく(ク・用) なり(四・用) に(助動・完・用) けり(助動・過・終)。 いま(副詞) 生ひ(上二段・用意) たる(助動・完・体) ぞ(係助、係り) 交じれ(四段・已然) る(助動・存続・体、結び)。 大方 の(格助) みな(副詞) 荒れ(下二段・用) に(助動・完了・用) たれ(助動・完了・已然) ば(接助)、「'''あはれ'''('''感嘆詞''')。」 と(格助) '''ぞ'''(係助、係り) 人々 言ふ(四段・連体、'''結び''')。 思ひ出で(下二・未然) ぬ(助動・打消し・体) こと なく(ク・用)、 思ひ恋しき(シク・体) が(格助) うち に(格助)、 こ(代) の(格助) 家 '''にて'''('''格助''') 生まれ(下二段・用) し(助動詞・過去・連体) 女子 の(格助) 、もろともに(副詞) 帰らね() ば(接助) 、 いかが(副詞) は(係助) 悲しき(シク・体)。 船人 も(係助) 、皆、 子 たかり() て(接助) ののしる()。 かかる(ラ変・連体) うち に(格助)、 なほ(副詞) 悲しき(シク・連体) に(格助) 堪へ(下二段・未然) ず(助動・未) '''して'''('''接助''')、 ひそかに(ナリ・用) 心 知れ(四・已) '''る'''(助動・'''存続'''・連体) 人 と(格助) 言へ(四・已) り(助動・完了・用) ける(助動・過去・連体) 歌、
:生まれ(下二段・用意) し(助動詞・過去・体) も(係助) 帰ら(四段・未然) ぬ(助動・打消・体) '''ものを'''('''接助''') わ(代名詞) が(格助) 宿 に(格助) 小松 の(格助) ある() を(格助) '''見る'''('''上一段'''・連体) が(格助) 悲しさ
と(格助) ぞ(係助、係り) 言へ(四段・已然) る(助動・完了・体、結び)。 なほ(副) 飽か(四段・未然) ず(助動詞・打消し・用) や(係助、係り) あら(ラ変・未然) む(助動・推量・連体、結び)、 また(副詞)、 かく(副詞) なむ(係助)。
:'''見'''('''上一段'''・用) し(助動・過去・体) 人 の(格助) 松 の(格助) 千年 に(格助) 見(上一段・未) '''ましか'''(助動・'''反実仮想'''・未然) ば(接助) 遠く(ク・用) 悲しき(シク・体) 別れ せ(サ変・未然) まし(助動・'''反実仮想'''・終) や(係助)
忘れがたく(ク・用)、 口惜しき(シク・体) こと 多かれ(ク・已然) ど(接助) 、'''え'''('''副詞''') 尽くさ() ず(助動・'''打消し'''・終止)。 とまれかうまれ(連語、音便) 、とく(ク・用) 破り(四・用) '''て'''('''助動詞'''・'''完了'''・未然) む(助動詞・意志・終止)。
== 第二グループ ==
=== 楫取りの心は神の御心 ===
=== 海賊の恐れ ===
=== 大津より浦戸へ ===
pglu0v581irhnke7v3jmn4q1ckslpzi
中学校社会 公民/日本における憲法と人権思想のあゆみ
0
22345
205802
201667
2022-07-25T00:01:51Z
はいかぐら
45848
wikitext
text/x-wiki
{| class="wikitable" style="float:right"
|+ 大日本帝国憲法と日本国憲法の比較
!大日本帝国憲法
|
! 日本国憲法
|-
| 天皇が決めた欽定(きんてい)憲法
! 性格
| 国民が決めた民定(みんてい)憲法
|-
| 天皇
! 主権者
| 日本国民
|-
| 法律の範囲内で<br /> 認める
! 国民の権利
| 生れながらにして<br /> 永久不可侵(ふかしん)の人権がある
|-
| 兵役、納税、(教育)
! 国民の義務
| 子女に普通教育を受けさせる、<br /> 勤労、納税
|-
| 天皇の協賛(きょうさん)機関
! 国会
| 国権の最高機関、唯一の立法機関
|-
| 天皇を助けて政治を行う
! 内閣
| 国会に対して責任を負う(議員内閣制)
|-
| 天皇の名において裁判を行う
! 裁判所
| 司法権(しほうけん)の独立
|-
|}
日本では、明治時代になってから、西洋の民主主義が、一般の人々に紹介されました。そして、自由民権運動が、盛り上がりました。
また、欧米諸国と対等な外交関係を築くためにも(※ 育鵬社の教科書の見解がこう。こう書いても教科書検定に通る。)、日本国は法体系を近代化する必要などもあって、明治時代のなかば、'''大日本帝国憲法'''(明治憲法)が制定・発布されました。
大日本帝国憲法は、日本で初めての、近代西洋的な意味での「人権」(human rights<ref>高等学校外国語科用『Standard Vision Quest English Logic and Expression I』、啓林館、令和3年3月5日検定済、令和3年12月10日発行、P111</ref>)を保障した憲法でもあります。
この明治憲法では、天皇が主権者であるという点が現代の憲法とは違いますし、人権が「法律の範囲内」という制限がつくという点も、現代の憲法とは違います。
:もっとも、現実の明治時代〜第二次大戦前の政治では、天皇は、普段はほとんど政治権力を行使することはなく、実際の政治は、内閣が行っていました。
なお、大日本帝国憲法で想定された人権は、現代でいえば、法律によらなければ死刑などで殺されない生命の権利や、財産を持つ権利などの、いわゆる自由権(じゆうけん)を中心としたものです。最低限度の生活を保障する社会権は、まだ1889年(大日本帝国憲法の制定年)当時の世界には浸透していませんでした(そもそも社会権が誕生したのが、1919年のドイツのワイマール憲法が世界で最初。それより前の時代の1889年の大日本帝国憲法が、社会権を保障するはずがないのは当然。)
第一次世界大戦後には、日本で、政党政治の普及を通じて民主主義が進展し(大正デモクラシー)、また、男子普通選挙が実現しました。
しかし、1930年代、満州事変が起きた前後のあたりから、しだいに軍部が権力をにぎっていくなかで、大日本帝国憲法の天皇が軍部を管轄しているという名目のため、国会や政党が、軍部の権力に歯止めをかける事が、しづらくなっていきました。
また、1925年に制定された治安維持法(ちあん いじほう)と、大日本帝国憲法の法律の範囲内で人権を制限できるという規定により、軍部に批判的な言論が、発表しづらくなっていきました。
そしてついに軍部は暴走していき、日本が第二次世界大戦へと突入していき、1945年の敗戦をむかえました。
1945年8月に、日本が、降伏(こうふく)勧告としての'''ポツダム宣言'''を受け入れたことで、公式には第二次世界大戦が終わりました。(※ 実際には、東南アジアなどでは、ヨーロッパ諸国による植民地支配から、現地住民が独立するための戦争が、続いていた。日本軍の現地部隊が、非公式に、現地住民の独立運動家などに武器を横流ししていたという説もある。)
そして、降伏した日本は、ポツダム宣言にある、戦後の民主化の方針のもと、憲法を改正する必要が生じました。
ポツダム宣言には、日本がしたがうべき方針としては、軍国主義を取り除くこと、民主主義を強化すること、基本的人権を尊重することなどが、定められています。
[[ファイル:Nihon Kenpo01.jpg|thumb|250px|日本国憲法の原本の一部]]
改憲案については、政党や民間の運動家などからも、さまざまな改憲の草案(そうあん)が出てきました。また、当初の政府案は、GHQにとっては民主化が不十分だとして認められず(※ 政府の当初案は、GHQには、大日本帝国憲法の語句を部分的に変えただけだと思われたようだ)、憲法を全面改正することになりました。
そして、最終的に、連合国軍総司令部(GHQ)が示した憲法草案をもとにした改憲案が、戦後の1946年に開かれた国会で審議され、1946年11月3日に'''日本国憲法'''として公布され、翌1947年5月3日から施行(しこう)されました。
5ur5x2bhhd2jl1gp65wrtt4l9mxgfzb
高等学校工業 土木施工/コンクリートの性質
0
22573
205806
205477
2022-07-25T00:26:31Z
Ef3
694
Fix typo; s/fresh cpncrete/fresh concrete/, s/無金コンクリート/無筋コンクリート/, s/AE剤/AE剤(Air Entraining Agent:空気連行剤)/
wikitext
text/x-wiki
* フレッシュコンクリート
コンクリートをつくるため、セメントなどのコンクリート原料に水などを加えて練り混ぜてから、まだ固まらない状態のコンクリートを'''フレッシュコンクリート'''(fresh concrete)という。
== フレッシュコンクリートの性質 ==
フレッシュコンクリートは、ある程度やわらかいほうが作業しやすいが、あまりにもやわらかすぎると、作業しづらくなる。
むしろ、ある程度は、変形や流動などの力が加えられたときに対してフレッシュコンクリートが抵抗できないと、作業中に目的の形状を保持できず、作業しづらい。(このように、コンクリートが力に抵抗する程度について、どのていど目的の形を保てるかという性質を'''コンシステンシー'''(consistency)という。)
=== スランプ試験 ===
フレッシュコンクリートのコンシステンシーを知るための試験として、'''スランプ試験'''がある。(※ 実教出版の『土木施行』の教科書では「スランプ試験」の用語は範囲外だが、普通の土木工学書の土木材料の書籍を読めば書いてある名称なので、覚えておこう。)
{{-}}
[[File:Slump test ja.svg|thumb|600px|left|スランプ試験]]
{{-}}
スランプ試験は、上図「スランプ試験」の説明のように、円錐状のコーンに入れたコンクリートを用意して、そのコーンを真上に引き上げると、コンクリートがくずれて高さが下がるので、どのくらい高さが下がったかを調べる試験である。
'''スランプ'''(slump)とは、上図のように、スランプ試験をしたときの、さがり具合、または、この現象のことである。
スランプ試験を行う際、コーンを引き上げようとする際、コーンの高さが30cmなので、コーンを引き上げるときは30cm以上まっすぐ上にコーンを引き上げる事になる。
そして、コーンを引き上げて、コンクリートの高さがどのくらい下がったかの値が'''スランプ値'''である。スランプ値を測るときは0.5cm単位で測定する。スランプ値の程度を伝えるときは、ふつう、cm単位で「スランプ◯◯cm」というふうに言う。
また、スランプ値のことを「スランプ」ともいう。
なお、スランプ試験に使うコーン、あの高さ30cmのコーンを「スランプコーン」という。※ 実教出版の『土木施行』の教科書では「スランプコーン」の用語は範囲外だが、普通の土木工学書の土木材料の書籍を読めば書いてある名称なので、覚えておこう。)
スランプ値が高すぎると、目的の形状を保てなくなるので、望ましいスランプ値の大きさとは、作業が可能な範囲で、スランプ値はなるべく小さいほうがいい。
{| class="wikitable" style="float:right"
|+ スランプの標準値
! colspan="2" |種類 !! スランプ<br />(cm)
|-
| rowspan="2" | 無筋コンクリート || 一般の場合 || 5〜12
|-
|| 断面の大きい場合 || 3〜10
|-
| rowspan="2" | 鉄筋コンクリート || 一般の場合 || 5〜12
|-
|| 断面の大きい場合 || 3〜10
|-
|}
:※ 右図「スランプの標準値」のスランプ値は、実教出版『土木施行』(検定教科書)より引用。なお、土木学会編「コンクリート標準示方書(施工編)」からの孫引き。
標準的なスランプの値は、だいたい3〜12cmである。AE剤(Air Entraining Agent:空気連行剤)を用いる場合は、だいたい 8〜18cmていどまでのスランプ値が標準である。(※ 参考文献: コロナ社『土木材料学』、中村聖三・奥松俊博 共著、2014年初版、37ページの表2.4「スランプの標準値」より、無金コンクリートおよび鉄筋コンクリートのスランプ値を参照。)
=== 空気の量 ===
コンクリート中に必要な空気の量は、およそ3〜6%である。
空気量が多すぎると強度の低下をまねくので、適切な値にする必要がある。
空気量の測定には、空気室圧力方式が、よく用いられる。
=== 材料の分離 ===
* ブリーディング
コンクリートの凝固・硬化につれ、水が上に上昇してきて、その結果、上表面には水やセメントの微粉が集まる。このような現象を'''ブリーディング'''(bleeding)という。
水は比重が小さいので上昇してくるのである。
* レイタンス
ブリーディングによって集まったセメント粉末などの微粒子が、水の蒸発後には、微粒子からなる層を形成する。この表面の微粒子からなる層を'''レイタンス'''(laitance)という。コンクリートを継ぎ足す際、レイタンスは付着力を下げるので、継ぎ足す前にレイタンスを削りとって除去する必要がある。
== 硬化したコンクリートの性質 ==
※ 圧縮試験の写真がウィキにないので、検定教科書を参照せよ。
dh4907a2albkocwb8fmkafivp500je2
Python/条件分岐と繰り返し
0
23162
205807
202878
2022-07-25T00:49:32Z
Ef3
694
/* break文 */ Fix typo
wikitext
text/x-wiki
{{Nav}}
Python の制御構造には、逐次・分岐・繰返しの3つがあり。このうち逐次はプログラムが左上から左から右・上から下に進む当たり前の状態ですので、これ以上の説明は必要ないと思います<ref>関数やメソッドの呼出しや復帰 return も制御構造と言えますが、本項では逐次・分岐・繰返しについて述べます。</ref>。
== 条件分岐 ==
条件分岐とは、ある条件を満たすかどうかで、次に実行するプログラムの位置を変えることです。
=== if文 ===
最も素朴な条件分岐は、単一のif文です<ref>{{Cite web
|url=https://docs.python.org/3/tutorial/controlflow.html#if-statements
|title=4.1. if Statements
|date=2021/11/17
|accessdate=2021/11/18
}}</ref>。
;if文による条件分岐:<syntaxhighlight lang="python" highlight="3,4" line>
x = 3
if x == 2 :
print("abcd")
</syntaxhighlight>
: 条件分岐の上のコードの、<code>x == 2</code>とは、「xは2に等しい」という意味です。
: 冒頭の「x = 3」は、xに3を代入するという意味です。
: python では、if文にある条件式にある等号と、代入との等号を区別するために、条件分岐での等号には<code>x == 2</code>を使います。
: 上のコードでは、「xは2に等しい」の条件を満たさないため(xには3が代入されている)、実行しても文「abcd」は表示されません。
: また、pythonでは、if文の中の文(ブロックと言います)は、字下げをします(この様なインデントによる構造構文をオフサイドルールと言います)。
: インデントは半角スペース4つが推奨されます。
;実行結果:<syntaxhighlight lang="text">
</syntaxhighlight>
※なにも表示されない。
つぎに、if文のなかのxの条件を変えてみて、条件が成り立つようにしましょう。
;条件が真になるように変更:<syntaxhighlight lang="python" highlight="3,4" line>
x = 3
if x == 3 :
print("abcd")
</syntaxhighlight>
:上のコードでは、「xは3に等しい」の条件を満たすので、実行したら文「abcd」が表示されます。
;実行結果:<syntaxhighlight lang="text">
abcd
</syntaxhighlight>
つまり、if文の構文は、次のようになります。
:<syntaxhighlight lang="python">
if 条件式 :
処理
</syntaxhighlight>
;if文のブロックの外に文を追加:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
</syntaxhighlight>
上のコードでは、print("ef")はif文のブロックの外にあることになります。
なぜなら、print("ef")は字下げされてないからです。
なので、プログラムを実行すると「ef」が表示されます。
いっぽう、次のコードでは、結果が変わります。
;if文のブロックに文を追加:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
</syntaxhighlight>
上のコードでは、print("ef")はif文ブロックの中にあるので、プログラムを実行しても、「ef」は表示されませんし、もちろん「abcd」も表示されません。
ifブロック内は、字下げをそろえないと、エラーになります。
;インデントに誤りのある例:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
</syntaxhighlight>
(↑エラーになる。)
下記コードでは、<code>x==2</code>が満たされていないので、インデントされたブロックは実行されない。そのため実行すると「プログラムが終了しました。」だけが表示される。
:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
print("プログラムが終了しました。")
</syntaxhighlight>
条件式には、不等号(<code>></code>や<code><</code>など)も使える。
:<syntaxhighlight lang="python">
x = 3
if x > 2 :
print("xは2よりも大きい。")
print("プログラムが終了しました。")
</syntaxhighlight>
上のコードを実行すると「xは2よりも大きいよ。」と「プログラムが終了しました。」が表示される。
==== 比較演算子 ====
記号<code>></code>のような、値を比較する演算子のことを比較演算子といいます。
pythonで使える比較演算子には、次の表のようなものがあります。
:{| class="wikitable"
|+ 比較演算子
|-
! 演算子 || 意味
|-
| <code>></code> || 左側の数が、右側の数よりも大きい
|-
| <code><</code> || 左側の数が、右側の数よりも小さい
|-
| <code>==</code> || 両辺の数値の大きさが等しい
|-
| <code>!=</code> || 等しくない
|-
| <code>>=</code> || 左側の数が、右側の数よりも大きいか、<br>または両辺が等しい
|-
| <code><=</code> || 左側の数が、右側の数よりも小さいか、<br>または両辺が等しい
|-
|}
==== in 演算子 ====
in 演算子は、オブジェクトがコレクションの要素にあるかを返します。
;[https://paiza.io/projects/1J09NAU1uBRn3u_wT11NBw?language=python3 in 演算子]:<syntaxhighlight lang="python">
li = [2,3,5]
tu = (10,20,30)
print(2 in li)
print(2 in tu)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
True
False
</syntaxhighlight>
=== else節のあるif文 ===
前の節では、if文の条件式によってブロックの実行/否を切り替えました。
ここでは、一歩進めて条件式に合致していなかった場合に別のブロックを実行する'''else節'''を含んだ条件実行構文を紹介します<ref>else節は、他の言語と違い[[#for文|for文]]とも結合しますので注意してください。</ref>。
;[https://paiza.io/projects/-myHVX1pJIcjPYS1grf7Aw?language=python3 else節のあるif文]:<syntaxhighlight lang="python" highlight="3-6" line>
x = 3
if x == 2 :
print("xは2に等しい。")
else :
print("xは2に等しくない。")
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xは2に等しくないよ。
プログラムが終了しました。
</syntaxhighlight>
なお、elseをつかわないでも、同じ内容の処理が書けます。
;else節を使わず、逆論理の別のif文を使った例:<syntaxhighlight lang="python" highlight="5-6" line>
x = 3
if x == 2 :
print("xは2に等しい。")
if x != 2 :
print("xは2に等しくない。")
print("プログラムが終了しました。")
</syntaxhighlight>
: 2つの例は同じ動作をしますが、後者は「変更漏れの原因となる」という重大な欠点があるので、好んで逆論理のif文を使わずelseを使いましょ。
=== elif節のあるif文 ===
else節を使うと、条件式によって2方向にプログラムフローを分けることができました。
実施のプログラムでは、2つ以上の条件式によってプログラムフローを分けることがあります。
そのような場合、次のように条件式ごとにif文が入れ子になります。
;[https://paiza.io/projects/-myHVX1pJIcjPYS1grf7Aw?language=python3 else節のあるif文]:<syntaxhighlight lang="python" highlight="3-12" line>
x = float("nan")
if x < 0 :
print("xは0より小さい。")
else :
if x > 0 :
print("xは0より大きい。")
else :
if x == 0 :
print("xは0と等しい。")
else :
print("xは", x)
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xはnan
プログラムが終了しました。
</syntaxhighlight>
このプログラムは意味的には正しいのですがインデントが深くなりすぎ、読むのも修正するのも難儀なので、Python にはelse節の中にif文が入れ子になっていことを表すキーワード '''elif''' が用意されています。
;[https://paiza.io/projects/Tn87qfpUbbh9xAIByzglKA?language=python3 elifによる置換え]:<syntaxhighlight lang="python" highlight="3-10" line>
x = float("nan")
if x < 0 :
print("xは0より小さい。")
elif x > 0 :
print("xは0より大きい。")
elif x == 0 :
print("xは0と等しい。")
else :
print("xは", x)
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xはnan
プログラムが終了しました。
</syntaxhighlight>
:インデントが深くなりすぎず読みやすいですね。
== if 式 ==
Python には、if文の他、if式があります。
;コード例:<syntaxhighlight lang="python">
x = 3
print("xは2に等しい。" if x == 2 else "xは2に等しくない。")
print("プログラムが終了しました。")
</syntaxhighlight>
:これで、else の例と同じ意味になります。
:[[Perl]]や[[Ruby]]の中置のifと似ていますが else を伴うので、[[C言語|C言語系]]の条件演算子と(構文はまるで違いますが)機能的には同じです。
:大概の場合、if文を使ったほうが読みやすいのですが、内包表記やラムダ式では式が要求されるので、if式を使う必要があります。
つまり、上記コードの実行結果は下記のようになります。
;実行結果:<syntaxhighlight lang="text">
xは2に等しくない。
プログラムが終了しました。
</syntaxhighlight>
{{コラム|nanってナニ?|2=
唐突に <code>float("nan")</code>、が出てきましたが、これがPythonでNaN(Not a Number; 非数)を得る方法で、他には math を import して math.nan を使う方法もあります。
nan は、浮動小数点演算の結果として、不正なオペランドを与えられたために生じた結果を表す値またはシンボルで<ref>ただし、Pythonでは math.asin(2) ↑ValueError であったりnanを返す前に例外が上がる事が多々ある。</ref>、NaNの体系的仕様は、無限大の表現などと共に1985年の IEEE 754 浮動小数点規格で標準が与えられています。
;nanの特徴
:どんな値と比較しても不一致
:: nan 自身とも一致しない( nan == nan ⇒ False )
:どんな数学関数の引数に与えても結果は nan
: nan であるかは is 演算子をつかう( nan is nan ⇒ True)
:: あるいは math を import し math.isnan(x) をつかう( isnan(nan) ⇒ True)
}}
=== 論理演算子 ===
「変数xは2より大きくて、5より小さい」ときにだけ実行するような処理は、次のように書きます。
:<syntaxhighlight lang="python">
x = 3
if x > 2 and x < 5 :
print("xは2より大きくて5より小さい。")
else:
print("そうでない場合。")
print("プログラムが終了しました。")
</syntaxhighlight>
<code>and</code>は、両方の条件が成り立つという意味です。
上記のコードを実行すると、「
xは2より大きくて5より小さいよ。
」が表示されます。「そうでない場合。」は表示されません。
xを6に変えてみましょう。
:<syntaxhighlight lang="python">
x = 6
if x > 2 and x < 5 :
print("xは2より大きくて5より小さい。")
else:
print("そうでない場合。")
print("プログラムが終了しました。")
</syntaxhighlight>
上記のコードを実行すると、「
そうでない場合。
」が表示されます。「xは2より大きくて5より小さいよ。」は表示されません。
演算子 <code>and</code>をもちいて、<syntaxhighlight lang="python">if 条件式A and 条件式B :</syntaxhighlight>
のように、使いうことにより、条件式Aと条件式Bが両方とも成り立つ場合に、「条件式A and 条件式B」が成り立つという意味にできます(数理論理学の用語でいう「論理積」です)。
{| class="wikitable"
|+ 論理演算子
|-
! 演算子 || 意味
|-
| <code>and</code> || 両方とも真。(「論理積」)
|-
| <code>or</code> || 片方または両方が真。(「論理和」)
|-
| <code>not</code> || 真ならば偽・偽ならば真。(「論理和」)
|}
{{コラム|複数の比較演算子の連結|
上記の例では、and 演算子の説明のため
* {{code| x > 2 and x < 5}}
としていますが、これは
* {{code| 2 < x < 5}}
と書くこともできます。両者は同じ意味になりますがxの参照は後者は一度だけになります。
}}
== match文 ==
Pythonには、[[C言語]]のswitch文はありませんでしたが、Python 3.10 から match 文がサポートされました<ref>{{Cite web
|url=https://docs.python.org/3/tutorial/controlflow.html##tut-match
|title=4.6. match Statements
|date=2021/11/17
|accessdate=2021/11/18
}}</ref>。
;match文を使った条件分岐:<syntaxhighlight lang="python">
for x in range(10):
print(x,"=", end=" ")
match x:
case 2:
print('two')
case 5:
print('five')
case 7:
print('seven')
case _:
print('ELSE')
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
0 = ELSE
1 = ELSE
2 = two
3 = ELSE
4 = ELSE
5 = five
6 = ELSE
7 = seven
8 = ELSE
9 = ELSE
</syntaxhighlight>
: switch文のdefault節に相当する機能は、case節 の値を _ にすることによって実現します。
match文は、2021年に導入された新しい機能なので、3.10 より古い3.9以下バージョンのpythonではmatch文は使えません。なので古いバージョンでは、if文などで代用してください。
=== 連想配列を使った多方向分岐 ===
上の例は、連想配列を使って下のように書き換えることができます。
;[https://paiza.io/projects/-c2_s18bUngaNFWE7KVdSQ?language=python3 連想配列を使った例]:<syntaxhighlight lang="python">
h = { 2: "two", 5: "five", 7: "seven"}
for x in range(10) :
print(f"{x} =", x in h and h[x] or "ELSE")
</syntaxhighlight>
=== 列挙型 ===
python では モジュール Enum で列挙型が提供されています<ref>{{Cite web
|url=https://docs.python.org/3/library/enum.html
|title=enum — Support for enumerations
|date=2021/11/17
|accessdate=2021/11/18
}}</ref>。
Enum はclassを用いる方法と、Enum関数を用いる方法の2つがありますが、ここでは class を用いる方法を紹介します。
;[https://paiza.io/projects/KVtAg0iVm1Ahnie7xxBazg?language=python3 列挙型]:<syntaxhighlight lang="python">
from enum import Enum
class GameMode(Enum):
map = 1
menu = 2
battle = 3
currentMode = GameMode.menu
assert currentMode in GameMode
if currentMode == GameMode.map:
print('マップ画面を探検中')
elif currentMode == GameMode.menu:
print('キャンプを開いて体制を整えよう')
elif currentMode == GameMode.battle:
print('敵襲!戦闘開始だ!')
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
キャンプを開いて体制を整えよう
</syntaxhighlight>
<code>map = 1</code> などのブロックの値は、べつに大小が順番どおりである必要はなく、それどころかWindowsで実験した限りは整数値である必要すらもなく小数値や数式ですら代入できてしまうのですが、しかしわざわざ分かりづらい数値を与える必要もないし、今後のバージョンの仕様変更なども想定して、なるべく普通の整数値を与えるのが安全だと思います。
なお、pythonの場合、enum変数をprint出力すると、下記のように格納された変数名(例の場合では"GameMode.menu")が出力されます。
enum変数自体には、「<GameMode.menu: 2>」のように変数名と値の両方のペアが格納されます。
それだけではenum変数を数値演算に活用できず不便なので、enum変数の数値を指定したい場合は下記のように<code>.value</code>プロパティを指定します。
<syntaxhighlight lang="python">
from enum import Enum
class GameMode(Enum):
map = 1
menu = 2
battle = 3
currentMode = GameMode.menu
assert currentMode in GameMode
if currentMode == GameMode.map:
print('マップ画面を探検中')
elif currentMode == GameMode.menu:
print('キャンプを開いて体制を整えよう')
elif currentMode == GameMode.battle:
print('敵襲!戦闘開始だ!')
print(currentMode)
print(repr(currentMode))
print(currentMode.value)
print(currentMode.name)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
キャンプを開いて体制を整えよう
GameMode.menu
<GameMode.menu: 2>
2
menu
</syntaxhighlight>
.nameプロパティは上記のように、GameMode.menu ではなく menu の部分だけを指定します。
他のプログラミング言語では、enum変数のprint表示の形式は違うかもしれないので、それぞれの言語のマニュアルを参照してください。
==== Enum.auto()の使用 ====
値をきめるのが面倒な場合、auto をインポートすれば、pythonが自動的にきめてくれます。
;Enum.auto()の使用:<syntaxhighlight lang="python">
from enum import Enum, auto
class GameMode(Enum):
map = auto()
menu = auto()
battle = auto()
currentMode = GameMode.map
assert currentMode in GameMode
if currentMode == GameMode.map:
print('マップ画面を探検中')
elif currentMode == GameMode.menu:
print('キャンプを開いて体制を整えよう')
elif currentMode == GameMode.battle:
print('敵襲!戦闘開始だ!')
print(currentMode.value)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
マップ画面を探検中
1
</syntaxhighlight>
==== __str__を定義 ====
メソッド __str__ を定義すると、str() をオーバーロードできます。
;[https://paiza.io/projects/cX9aQenQrAHK70RqJTqqQQ?language=python3 __str__を定義]:<syntaxhighlight lang="python">
from enum import Enum, auto
class GameMode(Enum):
map = auto()
menu = auto()
battle = auto()
def __str__(self) :
labels = {
self.map: "マップ画面を探検中",
self.menu:"キャンプを開いて体制を整えよう",
self.battle: "敵襲!戦闘開始だ!" }
return labels[self]
currentMode = GameMode.battle
print(currentMode)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
敵襲!戦闘開始だ!
</syntaxhighlight>
==== 別解 ====
列挙子の値は整数でなくてもよく、autoプロシージャを使うまでもなくメッセージ文字列そのものを値とし、値には self.value でアクセスしました。
併せて、クラスメソッドの実装例も追加しました。
;[https://paiza.io/projects/KGaaipDZmEKPwW_7oEQBSw?language=python3 別解]:<syntaxhighlight lang="python">
from enum import Enum
class GameMode(Enum):
map = "マップ画面を探検中"
menu = "キャンプを開いて体制を整えよう"
battle = "敵襲!戦闘開始だ!"
def __str__(self) :
return self.value
@classmethod
def names(cls):
return [e.name for e in cls]
@classmethod
def values(cls):
return [e.value for e in cls]
@classmethod
def hash(cls):
return {e.name: e.value for e in cls}
currentMode = GameMode.menu
print(currentMode)
print(GameMode.names())
print(GameMode.values())
print(GameMode.hash())
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
キャンプを開いて体制を整えよう
['map', 'menu', 'battle']
['マップ画面を探検中', 'キャンプを開いて体制を整えよう', '敵襲!戦闘開始だ!']
{'map': 'マップ画面を探検中', 'menu': 'キャンプを開いて体制を整えよう', 'battle': '敵襲!戦闘開始だ!'}
</syntaxhighlight>
== 繰返し ==
繰返しに関するPythonの構文には、[[#while文|while文]]と [[#for文|for文]]の2つがあります。
=== while文 ===
while 文は、ある条件を満たすあいだ、処理を繰返します。
;構文:<syntaxhighlight lang="python">
while 条件式 :
処理
</syntaxhighlight>
;コード例:<syntaxhighlight lang="python">
i = "b"
while i != "q":
i = input("入力した文字を3個、ならべるよ。(終了したい場合はqを入力)")
print(3*i)
</syntaxhighlight>
: 条件式は自動的に論理型に変換されます。
: 上記のプログラムを実行すると、まず「入力した文字を3個、ならべるよ。(終了したい場合はqを入力)」と言われる。
: 入力文字として、たとえば「a」と入力すると、「aaa」と出力表示され、そして再び「入力した文字を3個、ならべるよ。(終了したい場合はqを入力)」と聞かれ、ふたたび入力を待つ状態になる。なので、「b」と入力してみると、「bbb」と出力表示される。
: 上記のプログラムは、文字「q」が入力されないかぎり、動作がつづく。文字「q」を入力することにより、終了する。
==== 代入演算子 ====
上記の while 文の例は、代入演算子をつかうと、
;コード例(悪い例):<syntaxhighlight lang="python">
while (i := input("入力した文字を3個、ならべるよ。(終了したい場合はqを入力)")) != 'q' :
print(3*i)
</syntaxhighlight>
:のように書換えることができる。
==== while文とif文との組合わせ ====
while文はif文と組合わせることもできる。
;while文とif文との組合わせ(悪い例):<syntaxhighlight lang="python">
while (i := input("文字を入力しよう。sを入力で物語がスタート。(終了したい場合はqを入力)")) != 'q' :
if i == "s":
print("はじまりはじまり。")
print("むかし、むかし、あるところに、")
print("おじいさんとおばあさんが、すんでいました。")
print("おしまい")
</syntaxhighlight>
: 上記のプログラムを実行すると、文字「s」を入力することで「はじまりはじまり。」と表示させることができ、そして「むかし、むかし、あるところに、」「おじいさんとおばあさんが、すんでいました。」「おしまい」と表示する。
: sを入力しなければ、「はじまりはじまり。」などは表示されない。
::このコードは、while の条件式に入力のロジックと終了条件のロジックを合成して読解と修正を困難にしている悪い例です。[[#break文]]に改善した例があります。
=== for文 ===
;[https://paiza.io/projects/ZgzeneCdnkFDBkwmVOE1JA?language=python3 素朴なfor文]:<syntaxhighlight lang="python">
for i in range(5):
print("a")
</syntaxhighlight>
: のように書いて実行すると、組込み関数range()のカッコ内の回数だけ、ブロック内の文を繰り返す。上のコードの場合、実行すると、「a」を5回、表示する。
;実行結果:<syntaxhighlight lang=text>
a
a
a
a
a
</syntaxhighlight>
forのあとの変数(ループ変数と呼ばれます)は、別にiである必要はなく、特に以後値を参照しない場合は <var>_</var> を使うと慣習的に「参照しないこと」が明示できます。
;ループ変数が以後参照しないことを明示している例:<syntaxhighlight lang="python">
for _ in range(5):
print("a")
</syntaxhighlight>
ただし、あくまで慣習にすぎず、言語仕様上は <var>_</var> という名前の変数にすぎないので、<var>_</var> の値を参照するプログラムを書けば実行でき、インタプリターは何の警告もしません。
また、pylint の様な静的なソースコード診断ツールでは、<var>_</var> は未使用変数のチェックの対象から外されているなど、言語仕様ではないものの <var>_</var> を特別な識別子として扱う事は慣例的に定着しているので、<var>_</var> の値を参照するコードを書かないことを強く推奨します。
慣習上、for文を書くときは、i で回数を数えることが多い<ref>少なくともFortranではdo文のループ変数に i が常用され、それ以前に数学でも数列の和など i が使用される。由来は、iteration の i; integer の i など諸説あります。</ref>。
:<syntaxhighlight lang="python">
for i in range(5):
print(i)
</syntaxhighlight>
のように、すると、
;実行結果:<syntaxhighlight lang=text>
0
1
2
3
4
</syntaxhighlight>
のように表示されます。
組込み関数 range() は range クラスのオブジェクトを返します。
{{See also|Python/組込み関数#range}}
==== range以外のオブジェクトとfor文の組み合わせ ====
;[https://paiza.io/projects/azjiX8miD9GMLwcWjzq0YQ?language=python3 range以外のオブジェクトとfor文の組み合わせ]:<syntaxhighlight lang="python">
li = [2, 3, 5]
tu = (10, 20, 30)
for i in li:
print(i, end=", ")
else:
print()
for i in tu:
print(i, end=", ")
else:
print()
for i, j in zip(li, tu):
print(i, j, sep=":", end=", ")
else:
print()
print(type(zip(li, tu)))
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
2, 3, 5,
10, 20, 30,
2:10, 3:20, 5:30,
<class 'zip'>
</syntaxhighlight>
=== continue文 ===
continue文は、ループの先頭に戻ります。continue文を含むループのブロックのcontinue文以降は実行されません。
=== pass文 ===
pass文は、なにもしません。
「なにもしないが構文上ブロックが要求される」ケースで使われます。
=== break文 ===
while文あるいはfor文のブロックで文「break」を使うと、ループを中断します。
:<syntaxhighlight lang="python">
i = "b"
while True:
i = input("文字を入力しよう。sを入力で物語がスタート。(終了したい場合はqを入力))
if i == "s":
print("はじまりはじまり。")
print("むかし、むかし、あるところに、")
print("おじいさんとおばあさんが、すんでいました。")
print("おしまい")
elif i == "q":
break
</syntaxhighlight>
break文で中断する対象は、if文ではない。break文は、ループを中断するものです。
なお<code>while True</code>のように、while直後の条件式をブール値 True にすると、条件式は常に真となり、永久ループとなります<ref>{{code|while 1:}}としても無限ループになりますが、これは整数型が論理型に変換されるとき「0はFalse, 0以外はTrue」に暗黙に変換されることに頼っています(意味を明示するため{{code|while True:}}とすべき)。同様に{{code|while i:}}として、ループ変数 i がゼロになるまで繰り返すのようなコードも暗黙変換に頼っています。このようなコードは小さな変更で最初の意図に反した挙動を示します。たとえば i-=1 を i-=2 にした場合、i=1の次はi=-1となり、ループ終了条件のi=0を経ることなく無限ループになります。この場合は {{code|while i > 0:}}とすべきです。</ref>。
=== ループにつづくelse節 ===
'''while'''文あるいは'''for'''文が'''break'''文で'''中断しなかった場合'''、'''for'''につづく'''else'''節が実行されます。'''else'''節は、大概のプログラミング言語では'''if'''文と組合わせて使いますが、Pythonではこれに加え繰返し('''while'''文あるいは'''for'''文)と組合わせることができます。
==== while+else ====
;[https://paiza.io/projects/4s_1wWSiw8nbGB2jGNVjww?language=python3 while+else]:<syntaxhighlight lang="python">
i = 0
while i < 100:
print(i, end=" ")
i += 3
else:
print("done!")
i = 0
while i < 100:
if i > 10:
break
print(i, end=" ")
i += 3
else:
print("done!")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 done!
0 3 6 9
</syntaxhighlight>
:ループをカンストした場合は '''else''' 節を実行し、'''break''' (や '''return''')で中断すると '''else''' 節は実行されません。
==== for+else ====
;[https://paiza.io/projects/sM0j7iLBt7T2RipkLflGOw?language=python3 for+else]:<syntaxhighlight lang="python3">
h = {2: "two", 5: "five", 7: "seven"}
for x in list(h):
print(h[x])
else:
print("I didn't take a break.")
for x, v in h.items():
if x == 7:
break
print(x, v)
else:
print("I didn't take a break.")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
two
five
seven
I didn't take a break.
2 two
5 five
</syntaxhighlight>
:ループをカンストした場合は '''else''' 節を実行し、'''break''' (や '''return''')で中断すると '''else''' 節は実行されません。
{{コラム|ループとelseを組合わせた大域脱出|2=
Pythonはgoto分やラベル付きbreak文を持っていないので、大域脱出する場合は
*ループ全体を関数にしてreturn文で脱出
*tryをループをくくり例外をあげて脱出
*プログラム自身を終了
などの工夫が必要です。
ここでは、ループと結合したelseを使った大域脱出を紹介します。
;ループと結合したelseを使った大域脱出:<syntaxhighlight lang="python3" highlight='5,7-13' line>
for i in range(10):
for j in range(10):
for k in range(10):
if (i == 2 and j == 3 and k == 5):
break
print(f"{i}{j}{k}", end=" ")
else:
print()
continue
break
else:
continue
break
else:
print("done!")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
000 001 002 003 004 005 006 007 008 009
010 011 012 013 014 015 016 017 018 019
020 021 022 023 024 025 026 027 028 029
030 031 032 033 034 035 036 037 038 039
040 041 042 043 044 045 046 047 048 049
050 051 052 053 054 055 056 057 058 059
060 061 062 063 064 065 066 067 068 069
070 071 072 073 074 075 076 077 078 079
080 081 082 083 084 085 086 087 088 089
090 091 092 093 094 095 096 097 098 099
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
</syntaxhighlight>
:最外周の<code>print("done!")</code>は(breakされた場合は)実行されません。
}}
=== ループはスコープを作りません ===
Pythonでは、ループはスコープを作りません。
;[https://paiza.io/projects/TSbRsnv1oAaOQ3_5ErbRVg?language=python3 ループはスコープを作りません]:<syntaxhighlight lang="python">
i = "abc"
j = "xyz"
print(f"forの前: {i=}、{j=}")
for i in range(5):
j = 2 * i
print(f"forの中: {i=}、{j=}")
print(f"forの後: {i=}、{j=}")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
forの前: i='abc'、j='xyz'
forの中: i=0、j=0
forの中: i=1、j=2
forの中: i=2、j=4
forの中: i=3、j=6
forの中: i=4、j=8
forの後: i=4、j=8
</syntaxhighlight>
== 脚註 ==
<references />
jw4l93grdtxutsi8r1b9ba5w6g24nse
205808
205807
2022-07-25T00:58:54Z
Ef3
694
語尾の統一
wikitext
text/x-wiki
{{Nav}}
Python の制御構造には、逐次・分岐・繰返しの3つがあり。このうち逐次はプログラムが左上から左から右・上から下に進む当たり前の状態ですので、これ以上の説明は必要ないと思います<ref>関数やメソッドの呼出しや復帰 return も制御構造と言えますが、本項では逐次・分岐・繰返しについて述べます。</ref>。
== 条件分岐 ==
条件分岐とは、ある条件を満たすかどうかで、次に実行するプログラムの位置を変えることです。
=== if文 ===
最も素朴な条件分岐は、単一のif文です<ref>{{Cite web
|url=https://docs.python.org/3/tutorial/controlflow.html#if-statements
|title=4.1. if Statements
|date=2021/11/17
|accessdate=2021/11/18
}}</ref>。
;if文による条件分岐:<syntaxhighlight lang="python" highlight="3,4" line>
x = 3
if x == 2 :
print("abcd")
</syntaxhighlight>
: 条件分岐の上のコードの、<code>x == 2</code>とは、「xは2に等しい」という意味です。
: 冒頭の「x = 3」は、xに3を代入するという意味です。
: python では、if文にある条件式にある等号と、代入との等号を区別するために、条件分岐での等号には<code>x == 2</code>を使います。
: 上のコードでは、「xは2に等しい」の条件を満たさないため(xには3が代入されています)、実行しても文「abcd」は表示されません。
: また、pythonでは、if文の中の文(ブロックと言います)は、字下げをします(この様なインデントによる構造構文をオフサイドルールと言います)。
: インデントは半角スペース4つが推奨されます。
;実行結果:<syntaxhighlight lang="text">
</syntaxhighlight>
※なにも表示されません。
つぎに、if文のなかのxの条件を変えてみて、条件が成り立つようにしましょう。
;条件が真になるように変更:<syntaxhighlight lang="python" highlight="3,4" line>
x = 3
if x == 3 :
print("abcd")
</syntaxhighlight>
:上のコードでは、「xは3に等しい」の条件を満たすので、実行したら文「abcd」が表示されます。
;実行結果:<syntaxhighlight lang="text">
abcd
</syntaxhighlight>
つまり、if文の構文は、次のようになります。
:<syntaxhighlight lang="python">
if 条件式 :
処理
</syntaxhighlight>
;if文のブロックの外に文を追加:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
</syntaxhighlight>
上のコードでは、print("ef")はif文のブロックの外にあることになります。
なぜなら、print("ef")は字下げされてないからです。
なので、プログラムを実行すると「ef」が表示されます。
いっぽう、次のコードでは、結果が変わります。
;if文のブロックに文を追加:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
</syntaxhighlight>
上のコードでは、print("ef")はif文ブロックの中にあるので、プログラムを実行しても、「ef」は表示されませんし、もちろん「abcd」も表示されません。
ifブロック内は、字下げをそろえないと、エラーになります。
;インデントに誤りのある例:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
</syntaxhighlight>
(↑エラーになります。)
下記コードでは、<code>x==2</code>が満たされていないので、インデントされたブロックは実行されません。そのため実行すると「プログラムが終了しました。」だけが表示されます。
:<syntaxhighlight lang="python" highlight=5 line>
x = 3
if x == 2 :
print("abcd")
print("ef")
print("プログラムが終了しました。")
</syntaxhighlight>
条件式には、不等号(<code>></code>や<code><</code>など)も使えます。
:<syntaxhighlight lang="python">
x = 3
if x > 2 :
print("xは2よりも大きい。")
print("プログラムが終了しました。")
</syntaxhighlight>
上のコードを実行すると「xは2よりも大きいよ。」と「プログラムが終了しました。」が表示されます。
==== 比較演算子 ====
記号<code>></code>のような、値を比較する演算子のことを比較演算子といいます。
pythonで使える比較演算子には、次の表のようなものがあります。
:{| class="wikitable"
|+ 比較演算子
|-
! 演算子 || 意味
|-
| <code>></code> || 左側の数が、右側の数よりも大きい
|-
| <code><</code> || 左側の数が、右側の数よりも小さい
|-
| <code>==</code> || 両辺の数値の大きさが等しい
|-
| <code>!=</code> || 等しくない
|-
| <code>>=</code> || 左側の数が、右側の数よりも大きいか、<br>または両辺が等しい
|-
| <code><=</code> || 左側の数が、右側の数よりも小さいか、<br>または両辺が等しい
|-
|}
==== in 演算子 ====
in 演算子は、オブジェクトがコレクションの要素にあるかを返します。
;[https://paiza.io/projects/1J09NAU1uBRn3u_wT11NBw?language=python3 in 演算子]:<syntaxhighlight lang="python">
li = [2,3,5]
tu = (10,20,30)
print(2 in li)
print(2 in tu)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
True
False
</syntaxhighlight>
=== else節のあるif文 ===
前の節では、if文の条件式によってブロックの実行/否を切り替えました。
ここでは、一歩進めて条件式に合致していなかった場合に別のブロックを実行する'''else節'''を含んだ条件実行構文を紹介します<ref>else節は、他の言語と違い[[#for文|for文]]とも結合しますので注意してください。</ref>。
;[https://paiza.io/projects/-myHVX1pJIcjPYS1grf7Aw?language=python3 else節のあるif文]:<syntaxhighlight lang="python" highlight="3-6" line>
x = 3
if x == 2 :
print("xは2に等しい。")
else :
print("xは2に等しくありません。")
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xは2に等しくないよ。
プログラムが終了しました。
</syntaxhighlight>
なお、elseをつかわないでも、同じ内容の処理が書けます。
;else節を使わず、逆論理の別のif文を使った例:<syntaxhighlight lang="python" highlight="5-6" line>
x = 3
if x == 2 :
print("xは2に等しい。")
if x != 2 :
print("xは2に等しくありません。")
print("プログラムが終了しました。")
</syntaxhighlight>
: 2つの例は同じ動作をしますが、後者は「変更漏れの原因となる」という重大な欠点があるので、好んで逆論理のif文を使わずelseを使いましょ。
=== elif節のあるif文 ===
else節を使うと、条件式によって2方向にプログラムフローを分けることができました。
実施のプログラムでは、2つ以上の条件式によってプログラムフローを分けることがあります。
そのような場合、次のように条件式ごとにif文が入れ子になります。
;[https://paiza.io/projects/-myHVX1pJIcjPYS1grf7Aw?language=python3 else節のあるif文]:<syntaxhighlight lang="python" highlight="3-12" line>
x = float("nan")
if x < 0 :
print("xは0より小さい。")
else :
if x > 0 :
print("xは0より大きい。")
else :
if x == 0 :
print("xは0と等しい。")
else :
print("xは", x)
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xはnan
プログラムが終了しました。
</syntaxhighlight>
このプログラムは意味的には正しいのですがインデントが深くなりすぎ、読むのも修正するのも難儀なので、Python にはelse節の中にif文が入れ子になっていことを表すキーワード '''elif''' が用意されています。
;[https://paiza.io/projects/Tn87qfpUbbh9xAIByzglKA?language=python3 elifによる置換え]:<syntaxhighlight lang="python" highlight="3-10" line>
x = float("nan")
if x < 0 :
print("xは0より小さい。")
elif x > 0 :
print("xは0より大きい。")
elif x == 0 :
print("xは0と等しい。")
else :
print("xは", x)
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xはnan
プログラムが終了しました。
</syntaxhighlight>
:インデントが深くなりすぎず読みやすいですね。
== if 式 ==
Python には、if文の他、if式があります。
;コード例:<syntaxhighlight lang="python">
x = 3
print("xは2に等しい。" if x == 2 else "xは2に等しくありません。")
print("プログラムが終了しました。")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
xは2に等しくありません。
プログラムが終了しました。
</syntaxhighlight>
:これで、else の例と同じ意味になります。
:[[Perl]]や[[Ruby]]の後置のifと似ていますが else を伴うので、[[C言語|C言語系]]の条件演算子と(構文はまるで違いますが)機能的には同じです。
:大概の場合、if文を使ったほうが読みやすいのですが、内包表記やラムダ式では式が要求されるので、if式を使う必要があります。
{{コラム|nanってナニ?|2=
唐突に <code>float("nan")</code>、が出てきましたが、これがPythonでNaN(Not a Number; 非数)を得る方法で、他には math を import して math.nan を使う方法もあります。
nan は、浮動小数点演算の結果として、不正なオペランドを与えられたために生じた結果を表す値またはシンボルで<ref>ただし、Pythonでは math.asin(2) ↑ValueError であったりnanを返す前に例外が上がる事が多々あります。</ref>、NaNの体系的仕様は、無限大の表現などと共に1985年の IEEE 754 浮動小数点規格で標準が与えられています。
;nanの特徴
:どんな値と比較しても不一致
:: nan 自身とも一致しないです( nan == nan ⇒ False )
:どんな数学関数の引数に与えても結果は nan
: nan であるかは is 演算子をつかう( nan is nan ⇒ True)
:: あるいは math を import し math.isnan(x) をつかう( isnan(nan) ⇒ True)
}}
=== 論理演算子 ===
「変数xは2より大きくて、5より小さい」ときにだけ実行するような処理は、次のように書きます。
:<syntaxhighlight lang="python">
x = 3
if x > 2 and x < 5 :
print("xは2より大きくて5より小さい。")
else:
print("そうでない場合。")
print("プログラムが終了しました。")
</syntaxhighlight>
<code>and</code>は、両方の条件が成り立つという意味です。
上記のコードを実行すると、「
xは2より大きくて5より小さいよ。
」が表示されます。「そうでない場合。」は表示されません。
xを6に変えてみましょう。
:<syntaxhighlight lang="python">
x = 6
if x > 2 and x < 5 :
print("xは2より大きくて5より小さい。")
else:
print("そうでない場合。")
print("プログラムが終了しました。")
</syntaxhighlight>
上記のコードを実行すると、「
そうでない場合。
」が表示されます。「xは2より大きくて5より小さいよ。」は表示されません。
演算子 <code>and</code>をもちいて、<syntaxhighlight lang="python">if 条件式A and 条件式B :</syntaxhighlight>
のように、使いうことにより、条件式Aと条件式Bが両方とも成り立つ場合に、「条件式A and 条件式B」が成り立つという意味にできます(数理論理学の用語でいう「論理積」です)。
{| class="wikitable"
|+ 論理演算子
|-
! 演算子 || 意味
|-
| <code>and</code> || 両方とも真。(「論理積」)
|-
| <code>or</code> || 片方または両方が真。(「論理和」)
|-
| <code>not</code> || 真ならば偽・偽ならば真。(「論理和」)
|}
{{コラム|複数の比較演算子の連結|
上記の例では、and 演算子の説明のため
* {{code| x > 2 and x < 5}}
としていますが、これは
* {{code| 2 < x < 5}}
と書くこともできます。両者は同じ意味になりますがxの参照は後者は一度だけになります。
}}
== match文 ==
Pythonには、[[C言語]]のswitch文はありませんでしたが、Python 3.10 から match 文がサポートされました<ref>{{Cite web
|url=https://docs.python.org/3/tutorial/controlflow.html##tut-match
|title=4.6. match Statements
|date=2021/11/17
|accessdate=2021/11/18
}}</ref>。
;match文を使った条件分岐:<syntaxhighlight lang="python">
for x in range(10):
print(x,"=", end=" ")
match x:
case 2:
print('two')
case 5:
print('five')
case 7:
print('seven')
case _:
print('ELSE')
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
0 = ELSE
1 = ELSE
2 = two
3 = ELSE
4 = ELSE
5 = five
6 = ELSE
7 = seven
8 = ELSE
9 = ELSE
</syntaxhighlight>
: switch文のdefault節に相当する機能は、case節 の値を _ にすることによって実現します。
match文は、2021年に導入された新しい機能なので、3.10 より古い3.9以下バージョンのpythonではmatch文は使えません。なので古いバージョンでは、if文などで代用してください。
=== 連想配列を使った多方向分岐 ===
上の例は、連想配列を使って下のように書き換えることができます。
;[https://paiza.io/projects/-c2_s18bUngaNFWE7KVdSQ?language=python3 連想配列を使った例]:<syntaxhighlight lang="python">
h = { 2: "two", 5: "five", 7: "seven"}
for x in range(10) :
print(f"{x} =", x in h and h[x] or "ELSE")
</syntaxhighlight>
=== 列挙型 ===
python では モジュール Enum で列挙型が提供されています<ref>{{Cite web
|url=https://docs.python.org/3/library/enum.html
|title=enum — Support for enumerations
|date=2021/11/17
|accessdate=2021/11/18
}}</ref>。
Enum はclassを用いる方法と、Enum関数を用いる方法の2つがありますが、ここでは class を用いる方法を紹介します。
;[https://paiza.io/projects/KVtAg0iVm1Ahnie7xxBazg?language=python3 列挙型]:<syntaxhighlight lang="python">
from enum import Enum
class GameMode(Enum):
map = 1
menu = 2
battle = 3
currentMode = GameMode.menu
assert currentMode in GameMode
if currentMode == GameMode.map:
print('マップ画面を探検中')
elif currentMode == GameMode.menu:
print('キャンプを開いて体制を整えよう')
elif currentMode == GameMode.battle:
print('敵襲!戦闘開始だ!')
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
キャンプを開いて体制を整えよう
</syntaxhighlight>
<code>map = 1</code> などのブロックの値は、べつに大小が順番どおりである必要はなく、それどころかWindowsで実験した限りは整数値である必要すらもなく小数値や数式ですら代入できてしまうのですが、しかしわざわざ分かりづらい数値を与える必要もないし、今後のバージョンの仕様変更なども想定して、なるべく普通の整数値を与えるのが安全だと思います。
なお、pythonの場合、enum変数をprint出力すると、下記のように格納された変数名(例の場合では"GameMode.menu")が出力されます。
enum変数自体には、「<GameMode.menu: 2>」のように変数名と値の両方のペアが格納されます。
それだけではenum変数を数値演算に活用できず不便なので、enum変数の数値を指定したい場合は下記のように<code>.value</code>プロパティを指定します。
<syntaxhighlight lang="python">
from enum import Enum
class GameMode(Enum):
map = 1
menu = 2
battle = 3
currentMode = GameMode.menu
assert currentMode in GameMode
if currentMode == GameMode.map:
print('マップ画面を探検中')
elif currentMode == GameMode.menu:
print('キャンプを開いて体制を整えよう')
elif currentMode == GameMode.battle:
print('敵襲!戦闘開始だ!')
print(currentMode)
print(repr(currentMode))
print(currentMode.value)
print(currentMode.name)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
キャンプを開いて体制を整えよう
GameMode.menu
<GameMode.menu: 2>
2
menu
</syntaxhighlight>
.nameプロパティは上記のように、GameMode.menu ではなく menu の部分だけを指定します。
他のプログラミング言語では、enum変数のprint表示の形式は違うかもしれないので、それぞれの言語のマニュアルを参照してください。
==== Enum.auto()の使用 ====
値をきめるのが面倒な場合、auto をインポートすれば、pythonが自動的にきめてくれます。
;Enum.auto()の使用:<syntaxhighlight lang="python">
from enum import Enum, auto
class GameMode(Enum):
map = auto()
menu = auto()
battle = auto()
currentMode = GameMode.map
assert currentMode in GameMode
if currentMode == GameMode.map:
print('マップ画面を探検中')
elif currentMode == GameMode.menu:
print('キャンプを開いて体制を整えよう')
elif currentMode == GameMode.battle:
print('敵襲!戦闘開始だ!')
print(currentMode.value)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
マップ画面を探検中
1
</syntaxhighlight>
==== __str__を定義 ====
メソッド __str__ を定義すると、str() をオーバーロードできます。
;[https://paiza.io/projects/cX9aQenQrAHK70RqJTqqQQ?language=python3 __str__を定義]:<syntaxhighlight lang="python">
from enum import Enum, auto
class GameMode(Enum):
map = auto()
menu = auto()
battle = auto()
def __str__(self) :
labels = {
self.map: "マップ画面を探検中",
self.menu:"キャンプを開いて体制を整えよう",
self.battle: "敵襲!戦闘開始だ!" }
return labels[self]
currentMode = GameMode.battle
print(currentMode)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
敵襲!戦闘開始だ!
</syntaxhighlight>
==== 別解 ====
列挙子の値は整数でなくてもよく、autoプロシージャを使うまでもなくメッセージ文字列そのものを値とし、値には self.value でアクセスしました。
併せて、クラスメソッドの実装例も追加しました。
;[https://paiza.io/projects/KGaaipDZmEKPwW_7oEQBSw?language=python3 別解]:<syntaxhighlight lang="python">
from enum import Enum
class GameMode(Enum):
map = "マップ画面を探検中"
menu = "キャンプを開いて体制を整えよう"
battle = "敵襲!戦闘開始だ!"
def __str__(self) :
return self.value
@classmethod
def names(cls):
return [e.name for e in cls]
@classmethod
def values(cls):
return [e.value for e in cls]
@classmethod
def hash(cls):
return {e.name: e.value for e in cls}
currentMode = GameMode.menu
print(currentMode)
print(GameMode.names())
print(GameMode.values())
print(GameMode.hash())
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
キャンプを開いて体制を整えよう
['map', 'menu', 'battle']
['マップ画面を探検中', 'キャンプを開いて体制を整えよう', '敵襲!戦闘開始だ!']
{'map': 'マップ画面を探検中', 'menu': 'キャンプを開いて体制を整えよう', 'battle': '敵襲!戦闘開始だ!'}
</syntaxhighlight>
== 繰返し ==
繰返しに関するPythonの構文には、[[#while文|while文]]と [[#for文|for文]]の2つがあります。
=== while文 ===
while 文は、ある条件を満たすあいです、処理を繰返します。
;構文:<syntaxhighlight lang="python">
while 条件式 :
処理
</syntaxhighlight>
;コード例:<syntaxhighlight lang="python">
i = "b"
while i != "q":
i = input("入力した文字を3個、ならべるよ。(終了したい場合はqを入力)")
print(3*i)
</syntaxhighlight>
: 条件式は自動的に論理型に変換されます。
: 上記のプログラムを実行すると、まず「入力した文字を3個、ならべるよ。(終了したい場合はqを入力)」と言われます。
: 入力文字として、たとえば「a」と入力すると、「aaa」と出力表示され、そして再び「入力した文字を3個、ならべるよ。(終了したい場合はqを入力)」と聞かれ、ふたたび入力を待つ状態になります。なので、「b」と入力してみると、「bbb」と出力表示されます。
: 上記のプログラムは、文字「q」が入力されないかぎり、動作がつづく。文字「q」を入力することにより、終了します。
==== 代入演算子 ====
上記の while 文の例は、代入演算子をつかうと、
;コード例(悪い例):<syntaxhighlight lang="python">
while (i := input("入力した文字を3個、ならべるよ。(終了したい場合はqを入力)")) != 'q' :
print(3*i)
</syntaxhighlight>
:のように書換えることができます。
==== while文とif文との組合わせ ====
while文はif文と組合わせることもできます。
;while文とif文との組合わせ(悪い例):<syntaxhighlight lang="python">
while (i := input("文字を入力しましょう。sを入力で物語がスタート。(終了したい場合はqを入力)")) != 'q' :
if i == "s":
print("はじまりはじまり。")
print("むかし、むかし、あるところに、")
print("おじいさんとおばあさんが、すんでいました。")
print("おしまい")
</syntaxhighlight>
: 上記のプログラムを実行すると、文字「s」を入力することで「はじまりはじまり。」と表示させることができ、そして「むかし、むかし、あるところに、」「おじいさんとおばあさんが、すんでいました。」「おしまい」と表示します。
: sを入力しなければ、「はじまりはじまり。」などは表示されません。
::このコードは、while の条件式に入力のロジックと終了条件のロジックを合成して読解と修正を困難にしている悪い例です。[[#break文]]に改善した例があります。
=== for文 ===
;[https://paiza.io/projects/ZgzeneCdnkFDBkwmVOE1JA?language=python3 素朴なfor文]:<syntaxhighlight lang="python">
for i in range(5):
print("a")
</syntaxhighlight>
: のように書いて実行すると、組込み関数range()のカッコ内の回数だけ、ブロック内の文を繰り返す。上のコードの場合、実行すると、「a」を5回、表示します。
;実行結果:<syntaxhighlight lang=text>
a
a
a
a
a
</syntaxhighlight>
forのあとの変数(ループ変数と呼ばれます)は、別にiである必要はなく、特に以後値を参照しない場合は <var>_</var> を使うと慣習的に「参照しないこと」が明示できます。
;ループ変数が以後参照しないことを明示している例:<syntaxhighlight lang="python">
for _ in range(5):
print("a")
</syntaxhighlight>
ただし、あくまで慣習にすぎず、言語仕様上は <var>_</var> という名前の変数にすぎないので、<var>_</var> の値を参照するプログラムを書けば実行でき、インタプリターは何の警告もしません。
また、pylint の様な静的なソースコード診断ツールでは、<var>_</var> は未使用変数のチェックの対象から外されているなど、言語仕様ではないものの <var>_</var> を特別な識別子として扱う事は慣例的に定着しているので、<var>_</var> の値を参照するコードを書かないことを強く推奨します。
慣習上、for文を書くときは、i で回数を数えることが多い<ref>少なくともFortranではdo文のループ変数に i が常用され、それ以前に数学でも数列の和など i が使用されます。由来は、iteration の i; integer の i など諸説あります。</ref>。
:<syntaxhighlight lang="python">
for i in range(5):
print(i)
</syntaxhighlight>
のように、すると、
;実行結果:<syntaxhighlight lang=text>
0
1
2
3
4
</syntaxhighlight>
のように表示されます。
組込み関数 range() は range クラスのオブジェクトを返します。
{{See also|Python/組込み関数#range}}
==== range以外のオブジェクトとfor文の組み合わせ ====
;[https://paiza.io/projects/azjiX8miD9GMLwcWjzq0YQ?language=python3 range以外のオブジェクトとfor文の組み合わせ]:<syntaxhighlight lang="python">
li = [2, 3, 5]
tu = (10, 20, 30)
for i in li:
print(i, end=", ")
else:
print()
for i in tu:
print(i, end=", ")
else:
print()
for i, j in zip(li, tu):
print(i, j, sep=":", end=", ")
else:
print()
print(type(zip(li, tu)))
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
2, 3, 5,
10, 20, 30,
2:10, 3:20, 5:30,
<class 'zip'>
</syntaxhighlight>
=== continue文 ===
continue文は、ループの先頭に戻ります。continue文を含むループのブロックのcontinue文以降は実行されません。
=== pass文 ===
pass文は、なにもしません。
「なにもしないが構文上ブロックが要求される」ケースで使われます。
=== break文 ===
while文あるいはfor文のブロックで文「break」を使うと、ループを中断します。
:<syntaxhighlight lang="python">
i = "b"
while True:
i = input("文字を入力しましょう。sを入力で物語がスタート。(終了したい場合はqを入力))
if i == "s":
print("はじまりはじまり。")
print("むかし、むかし、あるところに、")
print("おじいさんとおばあさんが、すんでいました。")
print("おしまい")
elif i == "q":
break
</syntaxhighlight>
break文で中断する対象は、if文ではありません。break文は、ループを中断するものです。
なお<code>while True</code>のように、while直後の条件式をブール値 True にすると、条件式は常に真となり、永久ループとなります<ref>{{code|while 1:}}としても無限ループになりますが、これは整数型が論理型に変換されるとき「0はFalse, 0以外はTrue」に暗黙に変換されることに頼っています(意味を明示するため{{code|while True:}}とすべき)。同様に{{code|while i:}}として、ループ変数 i がゼロになるまで繰り返すのようなコードも暗黙変換に頼っています。このようなコードは小さな変更で最初の意図に反した挙動を示します。たとえば i-=1 を i-=2 にした場合、i=1の次はi=-1となり、ループ終了条件のi=0を経ることなく無限ループになります。この場合は {{code|while i > 0:}}とすべきです。</ref>。
=== ループにつづくelse節 ===
'''while'''文あるいは'''for'''文が'''break'''文で'''中断しなかった場合'''、'''for'''につづく'''else'''節が実行されます。'''else'''節は、大概のプログラミング言語では'''if'''文と組合わせて使いますが、Pythonではこれに加え繰返し('''while'''文あるいは'''for'''文)と組合わせることができます。
==== while+else ====
;[https://paiza.io/projects/4s_1wWSiw8nbGB2jGNVjww?language=python3 while+else]:<syntaxhighlight lang="python">
i = 0
while i < 100:
print(i, end=" ")
i += 3
else:
print("done!")
i = 0
while i < 100:
if i > 10:
break
print(i, end=" ")
i += 3
else:
print("done!")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 done!
0 3 6 9
</syntaxhighlight>
:ループをカンストした場合は '''else''' 節を実行し、'''break''' (や '''return''')で中断すると '''else''' 節は実行されません。
==== for+else ====
;[https://paiza.io/projects/sM0j7iLBt7T2RipkLflGOw?language=python3 for+else]:<syntaxhighlight lang="python3">
h = {2: "two", 5: "five", 7: "seven"}
for x in list(h):
print(h[x])
else:
print("I didn't take a break.")
for x, v in h.items():
if x == 7:
break
print(x, v)
else:
print("I didn't take a break.")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
two
five
seven
I didn't take a break.
2 two
5 five
</syntaxhighlight>
:ループをカンストした場合は '''else''' 節を実行し、'''break''' (や '''return''')で中断すると '''else''' 節は実行されません。
{{コラム|ループとelseを組合わせた大域脱出|2=
Pythonはgoto分やラベル付きbreak文を持っていないので、大域脱出する場合は
*ループ全体を関数にしてreturn文で脱出
*tryをループをくくり例外をあげて脱出
*プログラム自身を終了
などの工夫が必要です。
ここでは、ループと結合したelseを使った大域脱出を紹介します。
;ループと結合したelseを使った大域脱出:<syntaxhighlight lang="python3" highlight='5,7-13' line>
for i in range(10):
for j in range(10):
for k in range(10):
if (i == 2 and j == 3 and k == 5):
break
print(f"{i}{j}{k}", end=" ")
else:
print()
continue
break
else:
continue
break
else:
print("done!")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
000 001 002 003 004 005 006 007 008 009
010 011 012 013 014 015 016 017 018 019
020 021 022 023 024 025 026 027 028 029
030 031 032 033 034 035 036 037 038 039
040 041 042 043 044 045 046 047 048 049
050 051 052 053 054 055 056 057 058 059
060 061 062 063 064 065 066 067 068 069
070 071 072 073 074 075 076 077 078 079
080 081 082 083 084 085 086 087 088 089
090 091 092 093 094 095 096 097 098 099
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
</syntaxhighlight>
:最外周の<code>print("done!")</code>は(breakされた場合は)実行されません。
}}
=== ループはスコープを作りません ===
Pythonでは、ループはスコープを作りません。
;[https://paiza.io/projects/TSbRsnv1oAaOQ3_5ErbRVg?language=python3 ループはスコープを作りません]:<syntaxhighlight lang="python">
i = "abc"
j = "xyz"
print(f"forの前: {i=}、{j=}")
for i in range(5):
j = 2 * i
print(f"forの中: {i=}、{j=}")
print(f"forの後: {i=}、{j=}")
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
forの前: i='abc'、j='xyz'
forの中: i=0、j=0
forの中: i=1、j=2
forの中: i=2、j=4
forの中: i=3、j=6
forの中: i=4、j=8
forの後: i=4、j=8
</syntaxhighlight>
== 脚註 ==
<references />
10n4gl0pw9vt3x2p2oief4ym8oee5m3
高等学校理科 生物基礎/免疫
0
24799
205804
175850
2022-07-25T00:16:56Z
はいかぐら
45848
wikitext
text/x-wiki
=== リンパ系 ===
人体各部の組織液の一部は毛細血管に戻らず、毛細リンパ管に入り、リンパ管で合流して、'''リンパ液'''になる。リンパ管は流れ着く先は、最終的には、静脈に合流する。リンパ管には逆流を防ぐための弁が、ところどころにある。リンパ管のところどころに、球状にふくらんだ'''リンパ節'''がある。
リンパ液にふくまれる'''リンパ球'''(lymphocyte)は白血球の一種であり、マクロファージとともにリンパ球は異物を攻撃して、細菌などを排除する。
リンパ球はリンパ節で増殖する。
=== 生体防御 ===
外部環境から生体を守るために、異物の侵入を阻止したり、侵入した異物を白血球などが除去したりする仕組みを'''生体防御'''(せいたいぼうぎょ)と呼ぶ。
生体防御には、免疫、血液凝固、炎症などがある。
私たち生物の体は栄養豊富なので、もし生体防御の仕組みが無いと、あっという間に病原菌などが繁殖し、私たちは死んでしまう。そうならないのは、生体防御の仕組みが私たちを守っているからである。
生体が異物を非自己と認識して、その異物を排除する仕組みを'''免疫'''(めんえき、immunity)と呼ぶ。
免疫は、病原体や毒素を排除する働きを持つ。
免疫には、白血球の食作用などの先天的に生まれつき備わっている'''自然免疫'''(innate immunity)と、いっぽう、リンパ球などが抗原抗体反応によって異物の情報を記憶して排除するという後天的に獲得される'''獲得免疫'''(acquired immunity)がある(中学の保健体育で予習しているのも、このリンパ球による抗原抗体反応)。
:(※ 範囲外: ) 抗体による獲得免疫は、原則的にセキツイ動物(脊椎動物)しか持たない。 虫や昆虫などの非セキツイ動物は、抗体を作ることができない。しかし、実験動物でよく使われるショウジョウバエは、けっして病気にかかりやすいという事はなく、なんらかの免疫をもっている事が明らかである。このような観点から、20世紀後半には虫の免疫の研究も進み、1980〜1990年代には無脊椎動物のショウジョウバエのもつトル様受容体(Toll Like Receptor、トルよう じゅようたい)が細胞膜から発見された。このトル様受容体により、(セキツイ動物、無セキツイ動物を問わず)動物は大ざっぱに自己と非自己の認識をしている事が分かり、大ざっぱに自然免疫を制御している事が分かった。(一方、セキツイ動物の抗体による獲得免疫では、抗体の多様性により、病原体を細かく分類・認識できる。)トル様受容体を失ったショウジョウバエは、真菌(「しんきん」、いわゆるカビ、キノコなど)に容易に感染される事も明らかになった。
:その後、ハエや無脊椎動物だけでなく、人間も含む脊椎動物にもトル様受容体が存在する事が分かり、免疫学の理論が大きく書き変わる事となった。ヒトにもマウスにも魚にも、トル様受容体は存在する。
:これとは別に、「C型レクチン」というカルシウム依存性のタンパク質が見つかっており、ヒトから無セキツイ動物を含む多細胞生物全般からC型レクチンが見つかっており、このC型レクチンが(生物個体にとっての)異物(病原体など)を認識する事が分かっている。
なお、「RIG-I様レセプター」(リグアイようレセプター)という受容体が、専門書ではよくトル様レセプターと一緒に語られるが、しかし無セキツイ動物からはRIG-I様レセプターは発見されていない<ref>『マンガでわかる免疫学』76ページ </ref><ref>河本宏『もっとよくわかる! 免疫学』、2018年5月30日 第8刷、170ページ</ref>。このようなことから、RIG-I様レセプターは進化の歴史において、獲得免疫の進化とともにRIG-I様レセプターが備わっていったと思われている。
{{コラム|備考や注意喚起など|
(※ 備考、暗記は不要: )これ以外にも、免疫の機構について一説には、上記とは別の第三・第四の弱めの免疫の機構のある可能性を主張する学説もあるが、まだ未解明のことが多く、不明点も多い。
一説では、リンパ球による抗原抗体反応のほかにも、マクロファージなどの食細胞や樹状細胞などが弱めだが獲得免疫のような能力を獲得(?)する現象が起きる可能性もあるという学説があるが、未解明であり、正しいか間違ってるかも不明瞭であろう。(※ 学説は、正しいとは限らない。世界的な学会論文誌に掲載されてるからといって真実とは限らない。大学教科書に書いてあっても、真実とは限らない。)
(※ 注意喚起: ) ネットには免疫についてのデマが各所にあり(2020年現在)、「大学の医学教育では第三の免疫機構が常識」(×)みたいなデマがあるので、気をつけよ。念のため専門書の医学書で確認し、医学書院『標準免疫学 第3版』(2016年2月1日 第3版 第2刷)で確認したが、人体レベルでの免疫の機構は今のところ大学医学部の教育でも「自然免疫」と「獲得免疫」の2通りだけである。
なお「集団免疫」という医学用語があるが、これはある国や共同体などの住民たちの予防接種などによる獲得免疫によって、感染拡大の速度が遅くなるという統計の知られている事などを言っている。なので、「集団免疫」はべつに「獲得免疫」を否定するのものではない。
解明されている事実としては、マクロファージや樹状細胞などがMHC分子によってリンパ球のT細胞にどう情報伝達するかなども解明されてきているが(MHCは高校でも習う)、けっして、これは獲得免疫を否定する結果ではない。(おそらく、デマの何割かは、これを混同している。なぜなら世間には、高校教科書レベルの基礎知識もないのに先端医療を評論したがる人も多いのである。)
コレとは別件で、ガン治療などに関係して、免疫についてのうたがわしい話題もネットには多い。気をつけよ。
とりあえず確実な事として、高校の教科書でも習う、「リンパ球に獲得免疫の能力がある」という事は確実なので、高校生はまず、確実な定説から勉強しよう。未解明の学説の検証は、大人の仕事であり、給料をもらっている専門家の科学者たちのやるべき仕事である。
:先を見据えつつ、まず諸君らは基本を固めるべきである。
::(以上、備考)
}}
==== 自然免疫 ====
自然免疫は、好中球(neutrophil)、マクロファージ(単球)、樹状細胞(dendritic cell)、リンパ球といった白血球(leukocyte)が、病原体などの異物を食べる現象である'''食作用'''(Phagocytosis)で行われる。食べられた異物は、分解されて排除される。
* 好中球
好中球は自然免疫で、異物を食べて、除去する。攻撃した相手とともに死んでしまう細胞である。そのため寿命は短い。
ケガをしたときに傷口にできる膿は、好中球が死んだものである。
* マクロファージ
自然免疫で異物を食べる。あとで説明する獲得免疫に、異物の情報をつたえる。
:(※ 範囲外: )セキツイ動物だけでなく、昆虫などの無セキツイ動物からも、マクロファージのような食細胞は見つかっている。ただし、獲得免疫に情報を伝えるかどうかは別である。また、1892年、ロシアの微生物学者ミチニコフによる、ミジンコやナマコ(幼生)の研究からマクロファージが発見された。ミジンコもナマコも、無セキツイ動物。ミジンコは甲殻類であるが、無セキツイ動物。
近年、マクロファージや好中球などは、ある程度は異物の種類を認識している事が分かった。マクロファージや好中球や好中球などの細胞膜表面には'''トル様受容体'''(TLR)という受容体がある。
:(※ 範囲外: ) よって、抗体を持たない無セキツイ動物でも、ある程度は異物を認識できる事が解明された。
:(※ チャート式 生物でトル様受容体を扱っています。)
:(※ 検定教科書では、第一学習社の教科書などで扱っています。)
トル様受容体には、いくつかの種類があり、反応できる異物の種類が、トル受容体の種類ごとに、ある程度、(反応できる異物の種類が)限られている。
あるトル様受容体(TLR9)は、ウイルスのDNAやRNAを認識する。また他のあるトル様受容体(TLR2)は、細胞膜や細胞壁の成分を認識する。
(※ 読者への注意: TLR9などの具体的な番号は覚えなくてよい。ウィキブックス編集者が査読しやすいように補記してあるだけである。)
べん毛タンパク質を認識するトル様受容体(TLR5)もある。
:※ このように、トル様受容体の種類がいろいろとあることにより、白血球は異物の種類を、ある程度は認識できているという仕組みであると考えられている。
==== 免疫以外の生体防御 ====
* 血液凝固
出血したときは、血小板などの働きによってフィブリン(fibrin)と呼ばれる繊維状のタンパク質が合成され、
フィブリンが血球と絡み合って血餅(けっぺい, clot)となり止血する。
* 体液などの酸性
だ液(saliva)は弱酸性、胃液は強酸性などのように、外界と接する体液は、中性ではない体液によって、雑菌の繁殖を防いでいる。
また、ヒトの場合、皮膚は弱酸性である(※ 2016年センター『生物基礎』に出た)。これら酸性の環境によって、雑菌の繁殖を防いでいると思われる。
==== 獲得免疫 ====
獲得免疫には、後述する「体液性免疫」(たいえきせい めんえき、humoral immunity)と「細胞性免疫」(さいぼうせい めんえき、cell-mediated immunity)がある。
===== 体液性免疫 =====
[[File:免疫グロブリンの模式図.svg|320px|thumb|免疫グロブリンの構造]]
免疫グロブリンは、血液などの体液中に含まれている。
体液性免疫は、リンパ球の一部であるB細胞が、'''免疫グロブリン'''といわれる'''抗体'''(こうたい、antibody)を作り、(体液性免疫を)行う。抗体は'''免疫グロブリン'''(immunoglobulin、Igと略記)というタンパク質で構成されている。
:※ T細胞もB細胞も、リンパ球の一種である。(※ 高校では習わない言い回しだが、文脈によっては「Tリンパ球」や「Bリンパ球」という場合もある。好中球や好酸球などとT細胞やB細胞との関連を語る際、「Tリンパ球」「Bリンパ球」など言う場合もある。)
いっぽう、病原体などの異物に対して抗体が作られた時、その異物を'''抗原'''(こうげん、antigen)と呼ぶ。
抗原と抗体が反応することを'''抗原抗体反応'''(antigen-antibody reaction)と呼ぶ。
病原体などの抗原は、抗体と結合することで、毒性が低下し、また凝集するので、(リンパ球以外の)白血球による食作用を受けやすくなる。
※ なお、この文でいう「食作用」とは要するに、リンパ球以外の白血球が、細菌などを食べてしまう事。抗体の結合した細菌などを、「白血球が食べる」的な意味。
:(※ ほぼ範囲外: ) T細胞やB細胞といった「リンパ球」も分類上は白血球である。(※ 啓林館の教科書『生物基礎』(平成26年度用、128ページ)で、T細胞やB細胞が白血球に分類される事を紹介だけしている。
:東京書籍『生物基礎』(平成23年検定版、112ページ)では、図中でのみの説明で、T細胞やB細胞が白血球に分類される事と、白血球はもともと骨髄の「造血幹細胞」から成ることを紹介している。
:T細胞やB細胞が「リンパ球」である事を紹介している教科書は多いが、しかし、そのリンパ球は白血球に分類される事を説明している教科書が少ない。)
:(※ 以下、範囲外: 啓林の教科書にも説明なし)T細胞やB細胞がなぜ白血球であるかというと、好中球や好酸素球など同様に前駆細胞が同じだからである。T細胞は胸腺で成熟するが、胸腺に集まる前のT細胞の前駆細胞をたどっていくと、好中球や好酸球などと同様の造血幹細胞(ぞうけつ かんさいぼう)に行き着く<ref> 大地陸男『生理学テキスト』、文光堂、2017年8月9日 第8版 第2刷 発行、235ページ </ref>。なお、赤血球も白血球も骨髄(こつずい)で作られるので、つまりT細胞やB細胞の前駆物質も、好中球や好素球などの先駆物質も、おおもとは骨髄で作られる、という事を読者には意識してもらいたい。なお、「骨髄」(こつずい)とは、骨の内部にある造血細胞のこと。(よくある間違いで、脊椎(セキツイ)と混同されるが、異なるので、混同しないように。)
:(※ 範囲外: ) 本文に「抗体と結合することで、」「白血球による食作用を受けやすくなる。」とあるが、ここでいう、抗体との結合で食作用する「白血球」とは、好中球や好酸球や好塩基球のこと。好中球や好酸球や好塩基球の3つとも全部に抗体の結合した病原体を食作用する性質がある。<ref>小澤 瀞司/福田 康一郎 監修、医学書院『標準生理学 第8版』、2015年8月1日 第8版 第2刷発行、527ページ</ref>
免疫グロブリンによる免疫は、体液中の抗体による免疫なので、体液性免疫という。
* 免疫グロブリンの構造と機能
免疫グロブリンはY字型をしたタンパク質である。
免疫グロブリンの構造は、H鎖とL鎖といわれる2種類のポリペプチドが2個ずつ結合した構造になっている。図のように、免疫グロブリンは、合計4本のポリペプチドから構成されている。
H鎖とL鎖の先端部には'''可変部'''(かへんぶ、variable region)という抗体ごとに(免疫グロブリンの可変部の)アミノ酸配列の変わる部分があり、この部分(可変部)が特定の抗原と結合する。そして免疫グロブリンの可変部が抗原と結合することにより、免疫機能は抗原を認識して、一連の免疫反応をする。可変部の配列によって、認識する抗原の構造が異なる。
1種類の抗原に対応する抗体は1種類だけであるが、しかし上述のように可変部が変わりうるので、多種多様な抗原に対応できる仕組みになっている。
免疫グロブリンの構造において、可変部以外のほかの部分は'''定常部'''(ていじょうぶ、constant region)という。
また、H鎖同士、H鎖とL鎖は'''ジスルフィド(S-S)結合'''でつながっている。
* 体液性免疫の仕組み
そもそも免疫グロブリンはB細胞で産生される。免疫グロブリンの可変部の遺伝子も、元はと言えばB細胞の遺伝子が断片的に選択されて組み合わさったものである。このような遺伝子配列の組み合わせによって、配列のパターンが膨大に増えて何百万とおりにもなるので、このような仕組みによって多種多様な病原体(抗原)に対応している。
より細かく言うと、下記のような順序で、産生される。
樹状細胞などの食作用によって分解された断片が、抗原として提示される(抗原提示)。 そして、その抗原が、'''ヘルパーT細胞'''(ヘルパーティーさいぼう、helper T cell)によって認識される。
抗原を認識したヘルパーT細胞は活性化し、'''B細胞'''(ビーさいぼう)の増殖を促進する。
増殖したB細胞が、'''抗体産生細胞'''(こうたい さんせいさいぼう)へと分化する。
そして抗体産生細胞が、抗体として免疫グロブリンを産生する。
この抗体が、抗原と特異的に結合する('''抗原抗体反応''')。
抗原抗体反応によって、抗体と結合された抗原は毒性が弱まり、またマクロファージによって認識されやすくなり、マクロファージの食作用によって抗原が分解されるようになる。
* 利根川進(とねがわ すすむ)の業績
ヒトの遺伝子は数万種類であるといわれているが(※ 参考文献: 東京書籍の教科書、平成24検定版)、しかし抗体の種類はそれを膨大に上回り、抗体は数百万種類ていどにも対応する。
その仕組みは、B細胞の遺伝子から、選択的に抗体の遺伝子が選ばれるという仕組みになっている。この辺の抗体の種類の計算の仕組みは、1970年代ごろに日本人の生物学者の利根川進などによって研究されており、1987年には利根川進(とねがわ すすむ)はこの業績でノーベル医学・生理学賞を受賞した。
* その他
:(※ 範囲外:) 無セキツイ動物には抗体が無いが、しかしリンパのような組織が、タコや昆虫などからは見つかっている。<ref>[https://www.jstage.jst.go.jp/article/kagakutoseibutsu1962/30/7/30_7_422/_pdf/-char/ja 『比較免疫生物学の最近の展開』小野寺節, 423ページ ] </ref>
:なお、タコやイカは無セキツイ動物に分類される。
:(※ 範囲外: )これらB細胞やT細胞が実際に病原体を攻撃している事の証拠のひとつとしては、ヒトの遺伝病におけるB細胞欠損症の患者が容易に細菌感染をすること<ref>JEFFREY K.ACTOR 著、『免疫学・微生物学』東京化学同人、大沢利昭・今井康之 訳、2010年3月15日 第1版 発行、68ページ</ref>、および、T細胞欠損症の患者が容易にウイルス感染・真菌感染・原虫感染をする事<ref>JEFFREY K.ACTOR 著、『免疫学・微生物学』東京化学同人、大沢利昭・今井康之 訳、2010年3月15日 第1版 発行、68ページ</ref><ref>宮坂昌之ほか『標準免疫学』、医学書院、2016年2月1日 第3版 第2刷、397ページ</ref>などからも分かる。
===== 参考: ABO式血液型 =====
:(※ 東京書籍、啓林館、第一学習社などの検定教科書に記載あり。)
輸血は、血液型が同じ型どうしで輸血するの通常である。
赤血球表面に、抗原にあたる凝集原(ぎょうしゅうげん)AまたはBがある。なお、凝集原の正体は糖鎖である。
血清中に、抗体にあたる凝集素のαまたはβがある。この抗体は、病気の有無に関わらず、生まれつき持っている抗体である。
凝集原と凝集素との組み合わせによって、4つの型に分類される。
{| class="wikitable" style="float:right"
|+ ABO式血液型の凝集原と凝集素
! !! 凝集原(抗原) !! 凝集素(抗体)
|-
! A型
| A || β
|-
! B型
| B || α
|-
! AB型
| AB || なし
|-
! O型
| なし || α、β
|-
|}
Aとαが共存すると凝集する。
Bとβが共存すると凝集する。
たとえばA型の血をB型のヒトに輸血すると、赤血球が凝集してしまうので、輸血するのは危険である。
A型の糖鎖は、H型糖鎖という糖鎖の末端にNアセチルガラクトースアミン(GalNa)が結合している。
B型は、H型糖鎖という糖鎖の末端にガラクトース(Gal)が結合している。
AB型は、この両方の糖鎖が細胞膜にある。O型の糖鎖はH型糖鎖そのものだけである。
:(※ 余談 :) 輸血用の血液は、赤血球や血小板など、成分別に分けられ、輸血の際には必要な成分のみ輸血する。(※ 第一学習社の『新生物基礎』で紹介)
===== 細胞性免疫 =====
抗原提示されたヘルパーT細胞は、'''キラーT細胞'''(killer T cell)とよばれるT細胞を増殖させる。
キラーT細胞は、ウイルスに感染された自己の細胞を攻撃するが、移植細胞や がん細胞 も攻撃することもある。
細胞性免疫は、キラーT細胞が、抗原を直接攻撃して行う。
臓器移植や皮膚移植などで別の個体の臓器や皮膚などを移植すると、たとえ同種の個体からの移植でも、普通、定着しないで脱落する。これを'''拒絶反応'''という。これは細胞性免疫によって異物として移植臓器が認識され、キラーT細胞によって攻撃されたためである。
細胞膜の表面には、'''MHC'''('''主要組織適合性複合体'''、Major Histocompatibility Complex)というタンパク質がある。臓器移植で拒絶反応が起きる場合は、MHCが異なる場合であり、キラーT細胞が移植臓器を攻撃しているのである。
:※ 説明の簡単化のため、ヒトのMHCを想定して解説する。
MHCは個人ごとに異なるので、普通、他人とは一致しない。
T細胞は、相手方細胞の表面にあるMHCを認識している。つまりMHCの違いによって、ヘルパーT細胞が自己と非自己を認識する。そしてヘルパーT細胞が非自己の物質が侵入したことを感知して、キラーT細胞を活性化させる。
:(※ 範囲外: ) T細胞は原則的にセキツイ動物にしかないが、MHCもまたセキツイ動物にしかない<ref>河本宏『もっとよくわかる! 免疫学』、2018年5月30日 第8刷、170ページ</ref>。
なお、ヒトでは、ヒトの白血球の細胞表面にある'''ヒト白血球型抗原'''('''HLA'''、Human Leukocyte Antigen)がMHCとして機能する。血縁関係の無い他人どうしで、HLAが一致する確率は、ほとんど無い。同じ親から生まれた兄弟間で、HLAの一致は4分の1の確率である。移植手術の際、これらの免疫を抑制する必要があり、免疫抑制のために、あるカビから精製した「シクロスポリン」(ciclosporin)という名前の薬剤が、よく免疫抑制剤(めんえきよくせいざい)として使われる。(※ シクロスポリンはいちおう、高校の教科書で紹介されている。)<ref>浅島誠『生物基礎』東京書籍、平成26年2月発行、P.121</ref> <ref>吉田邦久『チャート式シリーズ要点と演習 新生物IB・II』東京書籍、P.121</ref>
:(※ 範囲外: )シクロスポリンと名前の似ている物質で、抗生物質の「セファロスポリン」があるので、混同しないように。
:(※ 範囲外: )妊娠歴のある女性や輸血を受けた経歴のある人には、免疫抑制剤が効かなくなる場合がある<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、301ページ</ref>。※ 高校教育的には、高校でこういう例外的な専門知識まで教えるわけにはいかないので、現在の高校理科ではあまり免疫抑制剤について教えてないことにも、それなりの理由がある。
臓器移植など移植手術での拒絶反応が起きる際の理由も、MHC(ヒトの場合はHLA)が異なって、T細胞が移植片を非自己と認識するからである(※ 参考文献: 第一学習社『高等学校生物』、24年検定版、26年発行、58ページ)、と考えられている。
:(※ 当カッコ内は範囲外: シクロスポリンはカルシニューリン阻害剤に分類されるのだが、細胞内におけるカルシウムによる情報伝達を阻害する事により、結果的にシクロスポリンは、免疫を抑制する。)
なおシクロスポリンは、T細胞によるサイトカイン(※ この「サイトカイン」とは細胞性免疫の情報伝達に関わる物質の一種であり、キラーT細胞などの他の免疫細胞を活性化させる役割を持っている)の産生を阻害することにより、細胞性免疫の作用を抑制している。(※ サイトカインは高校の範囲内)
:※ 「サイトカイニン」(植物ホルモンの一種)と「サイトカイン」は全く異なる別物質である。
:※ 検定教科箇所では、MHCの和訳を「主要組織適合性複合体」というかわりに「主要組織適合抗原」などという場合もある。大学の教科書でも、教科書出版社によって、どちらの表現を用いているかが異なっており、統一されていない。たとえば東京化学同人『免疫学の基礎』では「主要組織適合抗原系」という表現を用いている。羊土社『理系総合のための生命科学』では、「主要組織適合性複合体」を用いている。
:※ 余談だが、ヒトのHLA遺伝子の場所は解明されており、第6染色体に6対の領域(つまり12か所の領域)があることが分かっている。高校教科書でも図表などで紹介されている(※ 数年出版や第一学習者の教科書など)。(※ 入試にはまず出ないだろうから、暗記しないくて良いだろう。)
:いきなり「HLA遺伝子」と言う用語を使ったが、もちろん意味は、HLAを発現する遺伝子のことである。HLA遺伝子の対立遺伝子の数はけっこう多く、そのため、血縁者ではない他人どうしでは、まず一致しないのが通常である(※ 参考文献: 数研出版の教科書)、と考えられている。いっぽう、一卵性双生児では、HLAは一致する(※ 啓林館の教科書)、と考えられている。
:(※ 範囲外 :) 医学的な背景として、一卵性双生児では、移植手術の拒絶反応が起きづらいことが、実験的事実であるとして、知られている。
:また、医学書などでは、このような一卵性双生児の拒絶反応の起きづらい理由として、MHCが一致しているからだ、と結論づけている(※ 専門書による確認: 『標準免疫学』(医学書院、第3版、42ページ、ページ左段) に、MHCが同じ一卵性双生児では移植の拒絶反応が起きないという主旨の記述あり。)
:高校教科書の啓林館の教科書が、一卵性双生児にこだわるのは、こういう医学的な背景があるためだろう。
:なお、移植手術の歴史は以外と新しく、1950年代に人類初の、ヒトの移植手術が行われている。いっぽう、MHCの発見は、1940年代にマウスのMHC(マウスの場合はH-2抗原という)が発見されていた。
{{コラム|MHCあれこれ(※ 範囲外)|
※ MHCの話題のコラムが2つありますが、長いので分割したからです。
:※ 余談: (※ 覚えなくていい。一部の教科書にある発展的な記述。)
::MHCが糖タンパク質であることが分かっている(※ 数研出版の教科書で紹介)。
MHCの主な働きとして、移植などにおける自他の区別のほかにも、もう一つ別の働きがあり、それはT細胞に抗原ペプチドを情報伝達する役割がある。
(※ 検定教科書にあまり無い話題)B細胞は、単独で抗原と結合する事ができる。一方、T細胞は単独では結合できない(というのが定説である)<ref>熊ノ郷淳ほか『免疫学コア講義』、南山堂、2019年3月25日 4版 2刷、63ページ</ref>。
MHCをもつ一般の細胞は、病原体や非自己の有機物が入ってきたとき、それを分解して得られたタンパク質をMHCの上に乗せる。MHCに非自己のタンパク質が乗ったとき、T細胞側の受容体が、MHC と MHCの乗ったタンパク質 を抗原として認識する。
T細胞は、MHCによって、病原菌などの抗原を分解したペプチド(小分子のタンパク質)分子がMHC分子の溝にハマって細胞外に露出しており、T細胞はそうしてMHCに提示された「抗原ペプチド」を認識する仕組みにより、T細胞が抗原を認識する事が分かっている。
さて、MHCには主に2種類あり、クラスIとクラスIIに分類される(※ 数研出版の教科書で図中でのみ紹介)。
::(※ 出版社名不明: )MHCクラスIは主にキラーT細胞によって認識される。MHCクラスIIは、主にヘルパーT細胞によって認識される。
MHCクラスIは、ほとんどすべての有核細胞に存在する。
いっぽう、KHCクラスIIは、マクロファージ や 樹状細胞 や B細胞 や 胸腺上皮細胞 などに存在している。どうやらMHCクラスIIは、主に抗原提示細胞に存在していると思われている(と、どこかの検定教科書が言っているらしい)。
:(※ 範囲外 :)なお、なぜ、このようにMHCによる免疫の機構がクラスIとクラスIIに分かれているかというと、一説だが、たとえばマクロファージなどの食細胞は病原体も食べて病原体を分解してペプチド化してT細胞にペプチド断片を提示するのだが、もし(背理法の論法だが)ナイーブT細胞がマクロファージの食べた病原体の残骸をみてマクロファージを「こいつは病原体に感染した細胞だな。なので殺そう。」と誤って認識してしまいナイーブT細胞がキラーT細胞に変化してしまうと、(現実には起きないが、背理法的に)マクロファージがどんどん殺されてしまい、自然免疫を成さなくなって不合理だから・・・、なので不合理を避けるために、マクロファージなど食細胞はナイーブT細胞を活性化しづらい仕組みになっているのだろう、・・・というような感じの仮説もある<ref>河本宏『もっとよくわかる! 免疫学』、2018年5月30日 第8刷、45ページ</ref>。そのための仕組みとして、食細胞などはMHCのクラスが他の一般細胞のMHCとは別クラスになっているという学説である。ただし、樹状細胞にはMHCクラスIIのほかにMHCクラスIもあるので、キラーT細胞は樹状細胞も殺す事が分かっている。一見すると樹状細胞が殺されるには不合理のように見えるが、炎症を抑えるメカニズムだろうという学説がある。
:B細胞のMHCが(マクロファージと同様に)クラスIIなのも、おそらく上述のマクロファージや樹状細胞の理屈と関係があるのだろう、・・・という学説がある。
:(※ 小まとめ. )つまり、ほとんどすべての有核細胞は、キラーT細胞が、その細胞を(おそらくだが目的としては、キラーTが攻撃すべきかどうかの判定のために)認識することが、MHCクラスI分子によって可能である事になるだろう。
発達中のT細胞は胸腺で発達するが、胸腺皮質上皮細胞にはもMHCがあるのだが、なんと胸腺皮質上皮細胞のMHCクラスIと反応するT細胞はキラーT細胞になり、胸腺上皮のMHCクラスIIと反応するT細胞がヘルパーT細胞になる<ref>河本宏『もっとよくわかる! 免疫学』、2018年5月30日 第8刷、103ページ</ref><ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、163ページ</ref>という事まで、現在では解明されている。
上述のように、T細胞には、MHCを認識する受容体がある。なお、T細胞には、さらに多くの種類の受容体があり、MHCを認識する受容体以外にも、異なる機能をもった受容体が、いくつもある。
T細胞に存在する、抗原を認識する受容体のことを'''T細胞受容体'''(TCR)という。(※ いちおう、東京書籍と第一学習社の高校教科書にTCRの紹介があるが、他社の教科書には見られない。
::MHCの先端には、体内に侵入してきた病原体など有機の異物のタンパク質を分解した断片が、くっつけられ、提示される仕組みであり、(※ 第一学習社の教科書で紹介)「ペプチドMHC分子複合体」という。(ここでいう「ペプチド」とは、(タンパク質を構成している単位物質である)アミノ酸からなる化合物というような意味かと。)※ 東京書籍『生物』(専門生物)でも、用語は無いが、同等の機構を本文で紹介。
::(※ 範囲外: )「MHC」の用語の意味が20世紀の21世紀で若干変わり、MHCとは昔は(拒絶反応などに関わる)遺伝子のことだったので、(拒絶反応などに関わる)タンパク質のことを言う場合には、区別して(タンパク質のほうを)「MHC分子」というようになった。
::この「ペプチドMHC分子複合体」によって、MHCからT細胞に情報を送る仕組みである(クラス1もクラス2も、ヘルパーTかキラーTかの違いはあるが、送る先はともにT細胞である)。そして、有機の異物が侵入してない場合にも、MHCの先端には自己のタンパク質を分解した断片(いわゆる「自己ペプチド」)がくっつけられており、提示されている。自己タンパク質断片の提示される場合では、T細胞は提示された細胞を自己と認識するので、その場合にはT細胞は活性化されないという仕組みである。
<!-- ※ 調査中:) 侵入した異物がタンパク質やアミノ酸などを含まない場合の異物についてはどうか、専門書を見ても、書かれていない。文献では、異物として、最近やウイルスを構成するタンパク質を想定している文献ばかりだが、「では、栄養素などを構成するタンパク質やアミノ酸も、細胞は異物として認識するために細胞表面に抗原として提示するのかどうか?」については、残念ながら調査した文献の範囲内では書かれていなかった。-->
;その他
輸血のための血液を集める際、実は放射線を輸血バッグに照射してで輸血のT細胞などを殺している<ref>河本宏『もっとよくわかる! 免疫学』、2018年5月30日 第8刷、198ページ</ref>。
}}
{{コラム|「T細胞受容体」|
:(※ ほぼ範囲外)
:※ じつは「T細胞受容体」「TCR」の意味が、まだ専門家どうしにも統一していないようだ。現状、大きく分けて2種類の意味がある。
::・意味1: 文字通り、T細胞にある、抗原を認識するための受容体の総称。・・・という意味
::・意味2: MHCを認識する種類の受容体。・・・という意味
高校の検定教科書(東書、第一)では、主に「MHCを認識する種類の受容体。」の意味で使われている。
:※ 高校卒業以降の生物学の勉強のさいは、どちらの意味なのか、文脈から判断すること。大学レベルの教科書などを見ると、たとえば書籍の最初のほうではMHCを認識するタンパク質の意味として「TCR」を使っていたのに、書籍中の後半部で、T細胞の受容体の総称としての意味に「TCR」が変わっていたりする場合もある。(このように、意味が不統一なので、おそらく、あまり入試にTCRは出ないだろう。もし出るとしても、ここは暗記の必要は無いだろう。)
}}
* ツベルクリン反応
結核菌のタンパク質を投与して、結核菌に対しての免疫記憶があるかどうかを検査するのが'''ツベルクリン反応検査'''である。
結核菌への免疫があれば、炎症が起こり、赤く腫れる。この反応は細胞性免疫であり、ヘルパーT細胞やマクロファージの働きによるものである。
ツベルクリン反応をされて、赤く腫れる場合が陽性である。いっぽう、赤く腫れない場合が陰性である。
陰性のヒトは免疫が無いので、結核に感染する可能性があり、そのため免疫を獲得させるために弱毒化した結核菌が投与される。
BCGとは、この弱毒化した結核菌のことである。(つまり、結核のワクチンが、BCGワクチンである。なお「ツベルクリン」とは、ワクチンではなく、(「ツベルクリン」とは)結核診断のための(結核由来タンパク質を注射するなどの)検査方法<ref>岡崎勲ほか著『標準公衆衛生・社会医学 第2版』、医学書院、2009年3月1日 第2版 第1刷、187ページ</ref>のことである。)
* インターロイキン (※ 実教出版『生物基礎』(平成24年検定版、147ページ)にインターロイキンの説明をするコラムあり。数研出版と啓林館の専門生物(生物II)にも、記述あり。)
免疫細胞では、'''インターロイキン'''(interleukin)というタンパク質が、主に情報伝達物質として働いている。インターロイキンには、多くの種類がある。
インターロイキンのうち、いくつかの種類のものについては、ヘルパーT細胞からインターロイキンが放出されており、免疫に関する情報伝達をしている。
体液性免疫では、ヘルパーT細胞から(ある種類の)インターロイキンが放出されて、B細胞に情報が伝わっている。こうしてB細胞は抗体産生細胞に変化する。
:(※ 範囲外: )マウス実験により、X線照射でリンパ球を不活化することで免疫系を破壊したマウスに、外部からB細胞のみマウスに移植のグループ、T細胞のみ移植のグループ、B細胞とT細胞を移植のグループとの比較実験を行った結果、B細胞のみを移植してもマウスは抗体は産生されず、T細胞のみの移植でも抗体は産生されず、B細胞とT細胞の両方を移植しないとマウスに抗体が産生されない事が、実験的にも確認されている<ref>小山次郎・大沢利昭 著『免疫学の基礎 第4版』、東京化学同人、2013年8月1日 第5刷、113ページ</ref>。このように、B細胞の機能の発言には、T細胞も必要である。
細胞性免疫では、ヘルパーT細胞が(ある種類の)インターロイキンを放出し、キラーT細胞やマクロファージなどに情報が伝わる。
なお、名前の似ている「インターフェロン」という物質があるが、これはウイルスに感染した細胞から放出され、周囲の未感染細胞にウイルスの増殖を抑える物質を作らせる。(※ チャート式生物(平成26年版)の範囲。)
* 樹状細胞などの抗原提示について
[[File:MHC for beginners jp.svg|thumb|300px|MHCとT細胞受容体]]
マクロファージや樹状細胞も、病原体などを分解して、そのタンパク質断片を(マクロファージや樹状細胞の)細胞表面で抗原提示をして、ヘルパーT細胞を活性化する、・・・と考えられている。(※ 検定教科書では、MHCかどうかは、触れられてない。)
(※ まだ新しい分野でもあり、未解明のことも多く、高校生は、この分野には、あまり深入りしないほうが安全だろう。)
===== 免疫記憶 =====
T細胞やB細胞の一部は攻撃に参加せず、'''記憶細胞'''として残り、抗原の記憶を維持する。そのため、もし同じ抗原が侵入しても、1回目の免疫反応よりも、すばやく認識でき、すばやくT細胞やB細胞などを増殖・分化できる。
このため、すぐに、より強い、免疫が発揮できる。
これを'''免疫記憶'''(immunological memory)と呼ぶ。
一度かかった感染病には、再びは、かかりにくくなる。
これはリンパ球の一部が免疫記憶として病原体の情報を記憶しているためである。
免疫記憶は予防接種としても利用されている。
===== 免疫寛容 =====
免疫は、個体が未熟なときから存在する。成熟の課程で、リンパ球(T細胞)は、いったん多くの種類が作られ、あらゆる抗原に対応するので、自己の細胞も抗原と認識してしまうリンパ球もできる。いったん自分自身に免疫が働かないように、しかし、自己と反応したリンパ球は死んでいくので、個体の成熟の課程で、自己を排除しようとする不適切なリンパ球は取り除かれる。そして最終的に、自己とは反応しないリンパ球のみが、生き残る。
こうして、成熟の課程で、自己に対しての免疫が抑制される仕組みを'''免疫寛容'''(めんえき かんよう)という。
免疫寛容について、下記のことが分かっている。
まず、そもそも、T細胞もB細胞も、おおもとの原料となる細胞は、骨髄でつくられる。つまりリンパ球はすべて骨髄で作られる(※ 2015年センター試験の専門『生物』本試験でこういう問い方をしている)。
骨髄で作られた未成熟T細胞は、血流にのって胸腺まで運ばれ、胸腺でT細胞として分化・増殖する。
膨大なT細胞が作られる際、いったん、あらゆる抗原に対応できるようにT細胞がつくられるので、作られたT細胞のなかには自己の細胞を抗原として認識してしまうものも存在している。
しかし、分化・成熟の過程で、自己を攻撃してしまうT細胞があれば、その(自己を攻撃する)T細胞は胸腺で取り除かれる。
このようにして、免疫寛容が達成される。
このように、T細胞は胸腺に由来する。いっぽう、B細胞は胸腺には由来していない、と考えられている(※ B細胞の由来については検定教科書には明記されてないが、センター試験がこの見解。2016年生物基礎の追試験)。
==== 免疫の利用 ====
===== 予防接種 =====
殺しておいた病原体、あるいは無毒化や弱毒化させておいた病原体などを'''ワクチン'''という。このワクチンを、人間に接種すると、もとの病気に対しての抗体と免疫記憶を作らせることができるので、病気の予防になる。こうしてワクチンを接種して病気を予防することを'''予防接種'''という。
ワクチン療法の元祖は、18世紀なかばの医師ジェンナーによる、牛痘(ぎゅうとう)を利用した、天然痘(てんねんとう)の予防である。
天然痘は、死亡率が高く、ある世紀では、ヨーロッパ全土で100年間あたり6000万人もの人が死亡したとも言われている。天然痘はウイルスであることが、現在では知られている。
牛痘は牛に感染するが、人間にも感染する。人間に感染した場合、天然痘よりも症状は比較的軽い。
当事のヨーロッパで牛痘に感染した人は、天然痘には感染しにくい事が知られており、また牛痘に感染した人は天然痘に感染しても症状が軽い事が知られていた。このような話をジェンナーも聞いたようであり、牛の乳搾りをしていた農夫の女から聞いたらしい。
ジェンナーは、牛痘に感染した牛の膿を人間に接種することで、天然痘を予防する方法を開発した。
さらに19世紀末にパスツールがワクチンの手法を改良し、天然痘のワクチンを改良するとともに、狂犬病のワクチンなどを開発していった。
狂犬病はウイルスである。
現在では、天然痘のDNAおよび牛痘のDNAの解析がされており、天然痘と牛痘とは塩基配列が似ていることが分かっている。
1980年、世界保健機構(WHO)は、天然痘の根絶宣言を出した。
現在ではインフルエンザの予防にもワクチンが用いられている。インフルエンザには多くの型があり、年によって、流行している型がさまざまである。流行している型とは他の型のワクチンを接種しても、効果が無いのが普通である。
インフルエンザの感染は、鳥やブタやウマなどにも感染するのであり、けっしてヒトだけに感染するのではない。
インフルエンザはウイルスであり、細菌ではない。
インフルエンザのワクチンは、ニワトリの卵(鶏卵)の中で、インフルエンザウイルスを培養させた後、これを薬品処理して無毒化したものをワクチンとしている。このように薬品などで病原体を殺してあるワクチンを'''不活化ワクチン'''という。インフルエンザワクチンは不活化ワクチンである。いっぽう、結核の予防に用いられるBCGワクチンは、生きた弱毒結核菌である。BCGのように生きたワクチンを'''生ワクチン'''という。
1918年に世界的に流行したスペイン風邪も、インフルエンザである。
インフルエンザは変異しやすく、ブタなどに感染したインフルエンザが変異して、人間にも感染するようになる場合もある。
===== 血清療法 =====
ウマやウサギなどの動物に、弱毒化した病原体や、弱毒化した毒素などを投与し、その抗体を作らせる。その動物の血液の中には、抗体が多量に含まれることになる。
血液を採取し、そして血球やフィブリンなどを分離し、血清を回収すると、その血清の中に抗体が含まれている。
マムシやハブなどの毒ヘビにかまれた場合の治療として、これらのヘビ毒に対応した血清の注射が用いられている。このように血清をもちいた治療法を'''血清療法'''(けっせいりょうほう)という。血清療法は、免疫記憶は作らないので、予防には役立たない。予防ではなく治療のために血清療法を行う。
ヘビ毒以外には、破傷風(はしょうふう)やジフテリアなどの治療にも血清が用いられる。
血清療法は、1890年ごろ、北里柴三郎が開発した。
===== 白血病と骨髄移植 =====
(未記述)
==== 病気と免疫 ====
===== アレルギー =====
抗原抗体反応が過剰に起こることを'''アレルギー'''(allergy)と呼ぶ。スギ花粉などが原因で起きる'''花粉症'''もアレルギーの一つである。
アレルギーを引き起こす抗原を'''アレルゲン'''(allergen)と呼ぶ。
アレルギーのよって、じんましんが起きるきともある。
ヒトによっては卵やソバやピーナッツなどの食品もアレルゲンになりうる。、
ダニやホコリなどもアレルゲンになりうる。
抗原抗体反応によって、呼吸困難や血圧低下などの強い症状が起きる場合もあり、または全身に炎症などの症状が現れたりする場合もあり、このような現象を'''アナフィラキシー'''という。
(つまり、アレルギー反応によって、呼吸困難や血圧低下などの強い症状が起きる場合や、または全身に炎症などの症状が現れたりする場合もあり、このような現象を'''アナフィラキシー'''という。)
ハチ毒で、まれにアナフィラキシーが起きる場合がある。ペニシリンなどの薬剤でもアナフィラキシーが起きる場合がある。
※ 「アナフィラキシー・ショック」(anaphylactic shock)と書いても、正しい。(※ 東京書籍の検定教科書『生物基礎』平成23年検定版、124ページでは「アナフィラキシーショック」の用語で紹介している。)
:また、医学用語でも「アナフィラキシーショック」は使われる。(※ 参考文献: 医学書院『標準生理学 第8版』、657ページ、監修: 小澤 瀞司/福田 康一郎、発行:2015年8月1日。 『標準生理学』にて「アナフィラキシーショック」の用語を利用している。)
※ 「アナフィラキシー」の結果が、血圧低下なのか、それとも炎症なのかの説明が、検定教科書でもハッキリしていない。東京書籍の教科書では、全身の炎症を「アナフィラキシーショック」の症状として説明している。だが実教出版では、血圧低下や呼吸困難を、「アナフィラキシー」の結果としているし、「アナフィラキシーショック」とはアナフィラキシーの重症化した症状だと(実教出版は)説明している。
:※ 「ショック」という用語が医学用語で意味をもつが、高校理科の範囲外なので、あまり「アナフィラキシーショック」の用語には深入りしなくていい。「アナフィラキシー」で覚えておけば、大学入試対策では、じゅうぶんだろう。
:医学などでも、語尾に「ショック」のついてない「アナフィラキシー」という表現もよく使われるので、高校生は「アナフィラキシー」、「アナフィラキシーショック」の両方の言い回しとも覚えておこう。
===== HIV =====
'''エイズ'''('''後天性免疫不全症候群'''、'''AIDS''')の原因である'''HIV'''('''ヒト免疫不全ウイルス''')というウイルスは、ヘルパーT細胞に感染して、ヘルパーT細胞を破壊する。ヘルパーT細胞は免疫をつかさどる細胞である。そのため、エイズ患者の免疫機能が壊れ、さまざまな病原体に感染しやすくなってしまう。エイズ患者ではヘルパーT細胞が壊れているため、B細胞が抗体をつくることが出来ない。
ふつうのヒトでは発病しない弱毒の病原体でも、エイズ患者では免疫機能が無いため発症することもあり、このことを'''日和見感染'''(ひよりみ かんせん、opportunistic infection)という。
HIVとは Human Immunodeficiency Virus の略。
AIDSとは Acquired Immune Deficiency Syndrome の略。
HIVの遺伝子は変化をしやすく、そのため抗体を作成しても、遺伝子が変化しているので効果が無く、ワクチンが効かない。開発されているエイズ治療薬は、ウイルスの増加を抑えるだけである。
よって、予防が大事である。
===== 自己免疫疾患 =====
自己の組織や器官に対して、免疫が働いてしまい、その結果、病気が起きることを'''自己免疫疾患'''という。
関節リウマチ(rheumatoid arthritis)、重症筋無力症(myasthenia gravis)は自己免疫疾患である。I型糖尿病も自己免疫疾患である。
:(※ ほぼ範囲外?)甲状腺ホルモンの分泌過剰の病気であるバセドウ病(Basedow's Disease)の原因は、おそらく自己免疫疾患という説が有力である。書籍によってはバセドウ病は自己免疫疾患だと断定している。
:自己免疫疾患で、自己の甲状腺刺激ホルモンに対して抗体が作られてしまい、その抗体が甲状腺刺激ホルモンと似た作用を示し、抗体が甲状腺の受容体と結合して甲状腺ホルモンが過剰に分泌される、という仕組みがバセドウ病の原因として有力である。
:バセドウ病の症状では、眼球が突出するという症状がある。
==== その他 ====
ヒトの汗や鼻水や涙にはリゾチームという酵素があり、リゾチームは細菌の細胞壁を破壊する。<ref>『生物基礎』東京書籍、p.114</ref>
:※ セキツイ動物だけでなく、昆虫の体液からもリゾチームは発見されている<ref>[https://www.jstage.jst.go.jp/article/kagakutoseibutsu1962/20/9/20_9_580/_pdf/-char/ja 岩花秀典「昆虫の病原微生物に対する防御反応」582ページ ] </ref>。どうやら、動物全般に共通的に存在する自然免疫機構のひとつのようである。
{{コラム|(※ 範囲外) 「T細胞」と「B細胞」の名前の由来|
:※ 啓発林館の生物基礎など。
「T細胞」のTの語源は胸腺(Thymus)である。
「B細胞」の語源は、ニワトリなど鳥類にあるファブリキウス嚢(Bursa of Fabricus)である。研究の当初、まずニワトリのファブリキウス嚢が、ニワトリでは抗体産生に必要なことがわかった。また、ファブリキウス嚢を失ったニワトリは、抗体産生をしないことも分かった。
のちに、哺乳類では骨髄(Bone Marrow)でB細胞がつくられることが分かったが、偶然、Boneも頭文字がBであったので、名前を変える必要は無かったので、現代でもそのままB細胞と呼ばれている。
なお、動物実験で、ニワトリの(ファブリキウス嚢ではなく)胸腺を摘出した場合、この胸腺なしニワトリに(他の個体の皮膚を)皮膚移植をすれば他の個体の皮膚が定着する。
あるいは遺伝的に胸腺の無いヌードマウスなど、胸腺の無い個体の場合、拒絶反応が起きない。(第一学習社の「生物基礎」教科書で、遺伝的に胸腺の無いヌードマウスの皮膚移植を紹介。)
}}
{{コラム|ナチュラルキラー細胞(※ 範囲外:)|
:(※ 教科書にあまり無い話題: )
:※ 実教出版の『生物基礎』(平成24年検定版、145ページ)に、「NK細胞」と名前だけ紹介されている。
:※ 東京書籍『生物基礎』(平成23年検定済み)で、「ナチュラルキラー細胞」と紹介。
:チャート式にも、いちおう名前だけ紹介されている。
:※ 第一学習社『新生物基礎』で図表で紹介されている。
T細胞やB細胞とは別に、さらに「ナチュラルキラー細胞」(NK細胞)というのがリンパ球に含まれており、1970年代にナチュラルキラー細胞が発見されたが、まだよく解明されていない。
キラーT細胞などとの違いとしては、(ナチュラルキラー細胞でない単なる)T細胞なら別の免疫細胞によって抗原提示されてからT細胞が攻撃する。
(※ 実教および東京書籍の教科書にある記述)移植手術の際に、もし、家族でも何でもない他人の皮膚を移植すると脱落する拒絶反応が起きるのも、T細胞のほかNK細胞が移植片を攻撃するからである(という実教出版および東京書籍の見解)。
一方でナチュラルキラー細胞は、どうやら、なんの抗原提示を受けなくても、病原体感染細胞やガン細胞などを(ナチュラルキラー細胞が)攻撃するように観察されているので、「生まれつきの殺し屋」みたいな意味で、このような名前がついている。
:※ 実教出版の教科書でも、T細胞の指示を受けずにNK細胞がガン細胞を攻撃することを説明している。(実教出版『生物基礎』(平成24年検定版、145ページ))
このためか分類上では、ナチュラルキラー細胞は自然免疫の細胞であると分類されている<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、202ページ</ref>。だが、論文などでは、ナチュラルキラー細胞が場合によっては獲得免疫に似た免疫記憶の性質を持つ場合もあるとも報告されており<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、218ページ</ref>、まだ未解明であり、よく分かってない。
(※ なお、現在では、ナチュラルキラー細胞の働きを抑制する受容体なども相手先の体内の細胞側に発見されており(抑制性NKレセプター<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、22ページ</ref>)、NK細胞が本当に生まれつきナチュラルに殺す細胞かどうかは、検討の余地がある。)
とりあえず確実なこととして、T細胞やB細胞のほかに、ナチュラルキラー細胞というの発見されているのは事実である。
ナチュラルキラー細胞は、おそらくアポトーシスとも関連があるだろうとも見られている<ref>JEFFREY K.ACTOR 著、『免疫学・微生物学』東京化学同人、大沢利昭・今井康之 訳、2010年3月15日 第1版 発行、11ページ</ref>。
この他、キラーT細胞もアポトーシスに関連しているとされる<ref>JEFFREY K.ACTOR 著、『免疫学・微生物学』東京化学同人、大沢利昭・今井康之 訳、2010年3月15日 第1版 発行、31ページ</ref>。
なお、ナチュラルキラーT細胞(NKT細胞)というものも、発見されている。
NKT細胞とT細胞の違いとして、(一般の)T細胞やB細胞は糖タンパク質を抗原として認識するが、一方でナチュラルキラーT細胞(NKT細胞)は糖脂質を抗原として認識する<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、22ページ</ref>という、抗原の違いがあり、興味をもたれている<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、22ページ</ref>。
;NK細胞
(NKTでなく)ナチュラルキラ-細胞(NK細胞)は、MHCクラスI分子を持たない細胞(ミッシングセルフ細胞)を攻撃することが知られている。(どうやら、ガン細胞や病原体感染細胞などの異常細胞を攻撃するための仕組みであろう、と考えられている。)
実際、遺伝子操作されたマウスなどの動物実験などにより、ナチュラルキラー細胞を欠損したマウスでは、ガン発生率が確実に上昇している事が確認されている<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、215ページ</ref>。
また、試験管内の実験でも、NK細胞がガン細胞を殺傷する事が確認されている<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、215ページ</ref>。
NK細胞の抑制性レセプターとは、このMHCクラスI分子と、NK細胞との結合部分のことであろう、と考えられている。
;NKT細胞
動物実験によると、NKT細胞(ナチュラルキラーT細胞)を欠損したマウスは、病原体を除いた特殊環境(SPF環境)で飼育しないかぎり、乳幼児期にすべて死に絶えてしまう<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、226ページ</ref>。
NK細胞はガンを殺傷するが、NKT細胞もガンを殺傷する事が動物実験により分かっている。ある動物実験(マウス実験)では、化学発がん性物質メチルコナントレンをマウスに注射して人為的にマウスをガン化させようとする実験を試したところ、NKT欠損マウスは、NKTのあるマウよりも3~5倍も発ガン率が高かったという報告がある<ref>宮坂昌之ほか『標準免疫学』、医学書院、第3版、235ページ</ref>。
}}
{{コラム|セットポイント|
:※ 第一学習社の『新生物基礎』教科書で、セットポイントという用語を使わずに、風邪の際の発熱の仕組みを説明。
:概略であるので、あの人体図は無い。「視床下部」などの用語で説明する。
::※ 調査中 ※
}}
{{コラム|「MHC分子」や「MHC遺伝子」などの用語|
[[File:MHC molecule alias japanese.svg|thumb|300px|MHCとT細胞受容体]]
検定教科書には、あまり無い用語なのだが、入試過去問などでMHCについて、「MHC分子」および「MHC遺伝子」という用語がある。(※ 旺文社の標準問題精講あたりで発見。実は実教出版の検定教科書『生物基礎』に「MHC分子」だけ用語がある。)
この用語はどういう意味かと言うと、「MHC分子」とは、MHCの機能の受容体などに相当する、細胞膜表面のタンパク質のことである。
検定教科書や参考書のイラストなどで、細胞膜の表面にある受容体のようなものによく(※ 正確には、受容体ではなく、MHCの結合相手のT細胞受容体に結合する「リガンド」(※ 大学生物学の用語なので暗記は不要)だが)、単に「MHC」と明記してあるが、「MHC分子」とはその受容体っぽいものの事である。つまり、教科書イラストにある「MHC」が「MHC分子」の事である。
数研出版『生物基礎』の教科書では、「MHC抗原」と言ってる部分が、実教出版のいう「MHC分子」のことである。なお、東京書籍『生物』(専門生物)では、「MHCタンパク質」と言ってる部分でもある。
つまり、公式っぽくイコール記号で表せば
MHC抗原 = MHC分子 = MHCタンパク質
となる。
「分子」と言っても、けっして化学のH2O分子とかCO2分子のような意味ではない。
なお、第一学習社(教科書会社のひとつ)の専門『生物』の検定教科書では、単に「MHC」の3文字だけでMHC分子の事として言っているので、高校教育用語としては「MHC」だけでMHC分子の事を呼んでも正しい(でないと、教科書検定に、第一学習社の教科書が通らない)。
いっぽう、「MHC遺伝子」とは、MHC分子を作らせる遺伝子のこと。
歴史的には、「MHC」は用語の意味が微妙に変わっていき、もともとの「MHC」の意味は今で言う「MHC遺伝子」の意味だったのだが、しかし、次第に研究が進んだり普及するうちに、「MHC」だけだと読み手に混乱を起こすので、日本では意味に応じて「MHC分子」または「MHC遺伝子」などと使い分けるようになっている。
細胞膜のMHCのタンパク質部分の呼び名は英語が MHC molecule という言い方が主流なので、それを直訳すると「MHC分子」になるのだが(大学教科書でも「MHC分子」と表現している教材が多い)、しかしハッキリ言って、「分子」という表現は(少なくとも日本では、)やや誤解を招きやすい。(だから日本の高校教科書では、「MHC抗原」とか「MHCタンパク質」とか、いくつかの出版社がそういう言い方にしているのだろう。
なお、グーグル検索すると、 MHC antigen (直訳すると MHC 抗原)という表現も少々、出てくる。
さて、専門書だと、遺伝子のほうを単に「MHC」でゴリ押ししている書籍もあるが、しかし高校生むけの教材なら、遺伝子のほうを表すなら「MHC遺伝子」と説明するほうが合理的だろう。(だから旺文社の参考書でも「MHC遺伝子」表記になっているわけだ。)
}}
== (※ 参考:) RNA干渉 ==
近年、分子生物学の分野で「RNA干渉」という現象が知られており、一説ではそれが免疫と関連あるのでは?という仮説も提唱されている。
:※ 「RNA干渉」自体は高校でも習う。
:※ RNA干渉と免疫との関係説は、大学の範囲。大学でも、免疫学の専門書を読んでも習わない場合がある(たとえば医学免疫学の専門書には書かれてない)。
:※ RNA干渉および、それと免疫の関係について、wikibooksでは『[[高等学校生物/生物II/遺伝情報の発現#発展:_RNA干渉]]』に解説がある。
== 参考文献など ==
o0zmte0s9n11eivq6o2ky2skt2tsuyp
検定教科書/高等学校
0
28790
205797
205189
2022-07-24T17:40:03Z
Kwawe
68789
/* 農業 */
wikitext
text/x-wiki
{{Pathnav|メインページ|[[小学校・中学校・高等学校の学習]]>[[高等学校の学習]]>[[検定教科書]]|frame=1}}
このページでは、'''高等学校の教科書番号'''について説明します。教科書番号については、[[../|この上層ページ]]をご覧ください。
本内容は令和5年度以降の教科書目録をまとめています。
※以下、このページは新高校1年生から使う教科書を掲載しています。旧課程(現高校2~3年生)の教科書はこのページに掲載しておりません。
==国語==
※国語は本を読ますための性格なのか、A5版がほとんどです。
===現代の国語===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編現代の国語||A5判
|-
|702||東京書籍||精選現代の国語||A5判
|-
|703||東京書籍||現代の国語||A5判
|-
|704||三省堂||精選 現代の国語||A5判
|-
|705||三省堂||新 現代の国語||A5判
|-
|706||大修館書店||現代の国語||A5判
|-
|707||大修館書店||新編 現代の国語||B5判
|-
|708||数研出版||現代の国語||A5判
|-
|709||数研出版||高等学校 現代の国語||A5判
|-
|710||数研出版||新編 現代の国語||A5判
|-
|711||明治書院||精選 現代の国語||A5判
|-
|712||筑摩書房||現代の国語||A5判
|-
|713||第一学習社||高等学校 現代の国語||A5判
|-
|714||第一学習社||高等学校 精選現代の国語||A5判
|-
|715||第一学習社||高等学校 標準現代の国語||A5判
|-
|716||第一学習社||高等学校 新編現代の国語||B5判
|-
|717||桐原書店||探求 現代の国語||A5判
|-
|}
===言語文化===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編言語文化||A5判
|-
|702||東京書籍||精選言語文化||A5判
|-
|703||三省堂||精選 言語文化||A5判
|-
|704||三省堂||新 言語文化||A5判
|-
|705||大修館書店||言語文化||A5判
|-
|706||大修館書店||新編 言語文化||B5判
|-
|708||数研出版||高等学校 言語文化||A5判
|-
|709||数研出版||新編 言語文化||A5判
|-
|710||文英堂||言語文化||A5判
|-
|711||明治書院||精選言語文化||A5判
|-
|712||筑摩書房||言語文化||A5判
|-
|713||第一学習社||高等学校 言語文化||A5判
|-
|714||第一学習社||高等学校 精選言語文化||A5判
|-
|715||第一学習社||高等学校 標準言語文化||A5判
|-
|716||第一学習社||高等学校 新編言語文化||B5判
|-
|717||桐原書店||探求 言語文化||A5判
|}
===論理国語 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 論理国語 || A5判
|-
| 702 || 東京書籍 || 精選論理国語 || A5判
|-
| 703 || 三省堂 || 精選 論理国語 || A5判
|-
| 704 || 三省堂 || 新 論理国語 || A5判
|-
| 705 || 大修館書店 || |論理国語 || A5判
|-
| 706 || 大修館書店 || 新編 論理国語 || A5判
|-
| 707 || 数研出版 || 精選 論理国語 || A5判
|-
| 708 || 数研出版 || 論理国語 || A5判
|-
| 709 || 明治書院 || 精選 論理国語 || A5判
|-
| 710 || 筑摩書房 || 論理国語 || A5判
|-
| 711 || 第一学習社 || 高等学校 論理国語 || A5判
|-
| 712|| 第一学習社 || 高等学校 標準論理国語 || A5判
|-
| 713 || 桐原書店 || 探求 論理国語 || A5判
|}
===文学国語===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 文学国語 || A5判
|-
| 702 || 三省堂 || 精選 文学国語 || A5判
|-
| 703 || 三省堂 || 新 文学国語 || A5判
|-
| 704 || 大修館書店 || |文学国語 || A5判
|-
| 705 || 大修館書店 || 新編 文学国語 || A5判
|-
| 706 || 数研出版 || 文学国語 || A5判
|-
| 707 || 明治書院 || 精選 文学国語 || A5判
|-
| 708 || 筑摩書房 || 文学国語 || A5判
|-
| 709 || 第一学習社 || 高等学校 文学国語 || A5判
|-
| 710 || 第一学習社 || 高等学校 標準文学国語 || A5判
|-
| 711 || 桐原書店 || 探求 文学国語 || A5判
|}
===国語表現===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 大修館書店 || 国語表現 || B5判
|}
===古典探究 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社!! 教科書名!! 判型
|-
| 701 || 東京書籍 ||新編古典探究 || A5判
|-
| 702 || 東京書籍 ||精選古典探究 古文編 || A5判
|-
| 703 || 東京書籍 ||精選古典探究 漢文編 || A5判
|-
| 704 || 三省堂 ||精選 古典探究 古文編 || A5判
|-
| 705 || 三省堂 ||精選 古典探究 漢文編 || A5判
|-
| 706 || 大修館書店 ||古典探究 古文編 || A5判
|-
| 707 || 大修館書店 ||古典探究 漢文編 || A5判
|-
| 708 || 大修館書店 ||精選 古典探究 || A5判
|-
| 709 || 数研出版 ||古典探究 古文編 || A5判
|-
| 710 || 数研出版 ||古典探究 漢文編 || A5判
|-
| 711 || 数研出版 ||高等学校 古典探究 || A5判
|-
| 712 || 文英堂 ||古典探究 || A5判
|-
| 713 || 明治書院 ||精選 古典探究 古文編|| A5判
|-
| 714 || 明治書院 ||精選 古典探究 漢文編 || A5判
|-
| 715 || 筑摩書房 ||古典探究 古文編 || A5判
|-
| 716 || 筑摩書房 ||古典探究 漢文編 || A5判
|-
| 717 || 第一学習社 ||高等学校 古典探究 古文編 || A5判
|-
| 718 || 第一学習社 || 高等学校 古典探究 漢文編 || A5判
|-
| 719 || 第一学習社 || 高等学校 精選古典探究 || A5判
|-
| 720 || 第一学習社 || 高等学校 標準古典探究 || A5判
|-
| 721 || 桐原書店 || 探求 古典探究 古文編 || A5判
|-
| 722 || 桐原書店 || 探求 古典探究 漢文編 || A5判
|}
==地理歴史==
===地理総合===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 地理総合 || AB判
|-
| 702 || 実教出版 || 地理総合 || AB判
|-
| 703 || 帝国書院 || 高等学校 地理総合 || AB判
|-
| 704 || 二宮書店 || 地理総合 世界に学び地域へつなぐ || B5判
|-
| 705 || 二宮書店 || わたしたちの地理総合 世界から日本へ || AB判
|-
| 706 || 第一学習社 || 高等学校 地理総合 世界を学び、地域をつくる || AB判
|-
| 707 || 帝国書院 || 高校生の地理総合 || AB判
|}
===地理探究===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
| 701 ||東京書籍||地理探究||AB判
|-
|702||帝国書院||新詳地理探究||B5判
|-
|703||二宮書店|| 地理探究||B5判
|}
===歴史総合===
{| class="wikitable sortable"
|-
! 番号!! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新選歴史総合 || AB判
|-
| 702 || 東京書籍 || 詳解歴史総合 || B5判
|-
| 703 || 実教出版 || 詳述歴史総合 || B5判
|-
| 704 || 実教出版 || 歴史総合 || AB判
|-
| 705 || 清水書院 || 私たちの歴史総合 || A4判
|-
| 706 || 帝国書院 || 明解 歴史総合 || AB判
|-
| 707 || 山川出版社 || 歴史総合 近代から現代へ || B5判
|-
| 708 || 山川出版社 || 現代の歴史総合 みる・読みとく・考える || AB判
|-
| 709 || 山川出版社 || わたしたちの歴史 日本から世界へ || AB判
|-
| 710 || 第一学習社 || 高等学校 歴史総合 || AB判
|-
| 711 || 第一学習社 || 高等学校 新歴史総合 過去との対話、つなぐ未来 || AB判
|-
| 712 || 明成社 || 私たちの歴史総合 || B5判
|}
===日本史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 日本史探究 || B5判
|-
| 702 || 実教出版 || 日本史探究 || B5判変型
|-
| 703 || 実教出版 ||精選日本史探究 今につなぐ 未来をえがく || AB判
|-
| 704 || 清水書院 || 高等学校 日本史探究 || B5判
|-
| 705 || 山川出版社 || 詳説日本史 || B5判変型
|-
| 706 || 山川出版社 || 高校日本史|| B5判
|-
| 707 || 第一学習社 || 高等学校 日本史探究 || B5判
|}
===世界史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 世界史探究 || B5判
|-
| 702 || 実教出版 || 世界史探究 || B5判変型
|-
| 703 || 帝国書院 || 新詳世界史探究 || B5判
|-
| 704 || 山川出版社 || 詳説世界史 || B5判変型
|-
| 705 || 山川出版社 || 高校世界史 || B5判
|-
| 706 || 山川出版社 || 新世界史 || B5判変型
|-
| 707 || 第一学習社 || 高等学校 世界史探究 || B5判
|}
===地図===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新高等地図 || A4判
|-
| 702 || 帝国書院 || 新詳高等地図 || AB判
|-
| 703 || 帝国書院 || 標準高等地図 || A4判
|-
| 704 || 二宮書店 || 高等地図帳 || B5判
|-
| 705 || 二宮書店 || 詳解現代地図 最新版 || AB判
|-
| 706 || 二宮書店 || 基本地図帳 || A4判
|-
| 707 || 二宮書店 || コンパクト地理総合地図 || AB判変型
|}
==公民==
===公共===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||公共||AB判
|-
|702||教育図書||公共||B5判
|-
|703||実教出版||詳述公共||A5判
|-
|704||実教出版||公共||B5判
|-
|705||清水書院||高等学校 公共||B5判
|-
|706||清水書院||私たちの公共||AB判
|-
|707||帝国書院||高等学校 公共||AB判
|-
|708||数研出版||公共(令和4年度)||
|-
|709||数研出版||高等学校 公共 これからの社会について考える||AB判
|-
|710||第一学習社||高等学校 公共||B5判
|-
|711||第一学習社||高等学校 新公共||AB判
|-
|712||東京法令出版||公共||B5判
|-
|713||数研出版||新版 公共(令和5年度)||B5判
|}
===倫理===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 倫理 || B5判変型
|-
| 702 || 実教出版 || 詳述倫理 || A5判
|-
| 703 || 清水書院 || 高等学校 新倫理 || A5判
|-
| 704 || 数研出版 || 倫理 || A5判
|-
| 705 || 第一学習社 || 高等学校 倫理 || B5判
|}
===政治・経済===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
|701||東京書籍||政治・経済||B5判変型
|-
|702||実教出版||詳述政治・経済||A5判
|-
|703||実教出版||最新政治・経済||B5判
|-
|704||清水書院||高等学校 政治・経済||A5判
|-
|705||数研出版||政治・経済||A5判
|-
|706||第一学習社||高等学校 政治・経済||B5判
|}
==数学==
===数学Ⅰ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅰ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅰ Standard || A5判
|-
| 703 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学Ⅰ || B5判
|-
| 705 || 東京書籍 || 新数学Ⅰ 解答編 || B5判
|-
| 706 || 実教出版 || 数学Ⅰ Progress || A5判
|-
| 707 || 実教出版 || 新編数学Ⅰ || A5判
|-
| 708|| 実教出版 || 高校数学Ⅰ || B5判
|-
| 709 || 啓林館 || 数学Ⅰ || A5判
|-
| 710 || 啓林館 || 新編数学Ⅰ || A5判
|-
| 711 || 啓林館 || 深進数学Ⅰ || A5判
|-
| 712 || 数研出版 || 数学Ⅰ || A5判
|-
| 713 || 数研出版 || 高等学校 数学Ⅰ || A5判
|-
| 714 || 数研出版 || 新編 数学Ⅰ || A5判
|-
| 715 || 数研出版 || 最新 数学Ⅰ || A5判
|-
| 716 || 数研出版 || 新 高校の数学Ⅰ || B5判
|-
| 717 ||数研出版 || NEXT 数学Ⅰ || A5判
|-
| 718 || 第一学習社|| 新編数学Ⅰ || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Ⅰサポートブック || B5判変型版
|}
===数学Ⅱ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅱ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅱ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅱ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅱ || A5判
|-
| 705|| 実教出版 || 高校数学Ⅱ || B5判
|-
| 706 || 啓林館 || 数学Ⅱ || A5判
|-
| 707 || 啓林館 || 新編数学Ⅱ || A5判
|-
| 708 || 啓林館 || 深進数学Ⅱ || A5判
|-
| 709 || 数研出版 || 数学Ⅱ || A5判
|-
| 710 || 数研出版 || 高等学校 数学Ⅱ || A5判
|-
| 711 || 数研出版 || 新編 数学Ⅱ || A5判
|-
| 712 || 数研出版 || 最新 数学Ⅱ || A5判
|-
| 713 ||数研出版 || NEXT 数学Ⅱ || A5判
|-
| 714 || 第一学習社|| 新編数学Ⅱ || B5判変型版
|-
| 715 || 第一学習社 || 新編数学Ⅱサポートブック || B5判変型版
|-
| 716 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 717 || 東京書籍 || 新数学Ⅱ || B5判
|-
| 718 || 東京書籍 || 新数学Ⅱ 解答編 || B5判
|-
| 719 || 数研出版 || 新 高校の数学Ⅱ || B5判
|}
===数学Ⅲ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅲ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅲ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅲ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅲ || A5判
|-
| 705 || 啓林館 || 数学Ⅲ || A5判
|-
| 706 || 啓林館 || 新編数学Ⅲ || A5判
|-
| 707 || 啓林館 || 深進数学Ⅲ || A5判
|-
| 708 || 数研出版 || 数学Ⅲ || A5判
|-
| 709 || 数研出版 || 高等学校 数学Ⅲ || A5判
|-
| 710 || 数研出版 || 新編 数学Ⅲ || A5判
|-
| 711 || 数研出版 || 最新 数学Ⅲ || A5判
|-
| 712 ||数研出版 || NEXT 数学Ⅲ || A5判
|}
===数学A===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学A Advanced || A5判
|-
| 702 || 東京書籍 || 数学A Standard || A5判
|-
| 703 || 東京書籍 || 数学A Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学A || B5判
|-
| 705 || 東京書籍 || 新数学A 解答編 || B5判
|-
| 706 || 実教出版 || 数学A Progress || A5判
|-
| 707 || 実教出版 || 新編数学A || A5判
|-
| 708|| 実教出版 || 高校数学A || B5判
|-
| 709 || 啓林館 || 数学A || A5判
|-
| 710 || 啓林館 || 新編数学A || A5判
|-
| 711 || 啓林館 || 深進数学A || A5判
|-
| 712 || 数研出版 || 数学A || A5判
|-
| 713 || 数研出版 || 高等学校 数学A || A5判
|-
| 714 || 数研出版 || 新編 数学A || A5判
|-
| 715 || 数研出版 || 最新 数学A || A5判
|-
| 716 || 数研出版 || 新 高校の数学A || B5判
|-
| 717 ||数研出版 || NEXT 数学A || A5判
|-
| 718 || 第一学習社|| 新編数学A || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Aサポートブック || B5判変型版
|}
===数学B===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学B Advanced || A5判
|-
| 702 || 東京書籍 || 数学B Standard || A5判
|-
| 703 || 東京書籍 || 数学B Essence || B5判変型版
|-
| 704 || 実教出版 || 数学B Progress || A5判
|-
| 705 || 実教出版 || 新編数学B || A5判
|-
| 706|| 実教出版 || 高校数学B || B5判
|-
| 707 || 啓林館 || 数学B || A5判
|-
| 708 || 啓林館 || 新編数学B || A5判
|-
| 709 || 啓林館 || 深進数学B || A5判
|-
| 710 || 数研出版 || 数学B || A5判
|-
| 711 || 数研出版 || 高等学校 数学B || A5判
|-
| 712 || 数研出版 || 新編 数学B || A5判
|-
| 713 || 数研出版 || 最新 数学B || A5判
|-
| 714 || 数研出版 || 新 高校の数学B || B5判
|-
| 715 ||数研出版 || NEXT 数学B || A5判
|-
| 716 || 第一学習社|| 新編数学B || B5判変型版
|}
===数学C===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学C Advanced || A5判
|-
| 702 || 東京書籍 || 数学C Standard || A5判
|-
| 703 || 実教出版 || 数学C Progress || A5判
|-
| 704 || 実教出版 || 新編数学C || A5判
|-
| 705 || 啓林館 || 数学C || A5判
|-
| 706 || 啓林館 || 新編数学C || A5判
|-
| 707 || 啓林館 || 深進数学C || A5判
|-
| 708 || 数研出版 || 数学C || A5判
|-
| 709 || 数研出版 || 高等学校 数学C || A5判
|-
| 710 || 数研出版 || 新編 数学C || A5判
|-
| 711 || 数研出版 || 最新 数学C || A5判
|-
| 712 || 数研出版 || NEXT 数学C || A5判
|-
| 713 || 第一学習社 || 新編数学C || B5判変型
|}
==理科==
===科学と人間生活===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 科学と人間生活 || B5判変型
|-
| 702 || 実教出版 || 科学と人間生活 || B5判
|-
| 703 || 啓林館 || 高等学校 科学と人間生活 || B5判
|-
| 704 || 数研出版 || 科学と人間生活 || AB判
|-
| 705 || 第一学習社 || 高等学校 科学と人間生活 || B5判
|}
===物理基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|物理基礎
|B5判変型
|-
|702
|東京書籍
|新編物理基礎
|B5判
|-
|703
|実教出版
|物理基礎
|B5判
|-
|704
|実教出版
|高校物理基礎
|B5判
|-
|705
|啓林館
|高等学校 物理基礎
|A5判
|-
|706
|啓林館
|高等学校 考える物理基礎
|B5判
|-
|707
|数研出版
|物理基礎
|A5判
|-
|708
|数研出版
|新編 物理基礎
|B5判
|-
|709
|第一学習社
|高等学校 物理基礎
|B5判変型
|-
|710
|第一学習社
|高等学校 新物理基礎
|B5判
|}
===物理===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|物理
|B5判変型
|-
|702
|実教出版
|物理
|B5判
|-
|703
|啓林館
|高等学校 物理
|A5判
|-
|704
|啓林館
|高等学校 総合物理1 様々な運動 熱 波
|A5判
|-
|705
|啓林館
|高等学校 総合物理2 電気と磁気 原子・分子の世界
|A5判
|-
|706
|数研出版
|物理
|A5判
|-
|707
|数研出版
|総合物理1 力と運動・熱
|A5判
|-
|708
|数研出版
|総合物理2 波・電気と磁気・原子
|A5判
|-
|709
|第一学習社
|高等学校 物理
|B5判変型
|}
===化学基礎===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学基礎
|B5判変型
|-
|702
|東京書籍
|新編化学基礎
|B5判
|-
|703
|実教出版
|化学基礎 academia
|A5判
|-
|704
|実教出版
|化学基礎
|B5判
|-
|705
|実教出版
|高校化学基礎
|B5判
|-
|706
|啓林館
|高等学校 化学基礎
|A5判
|-
|707
|啓林館
|i版 化学基礎
|AB判
|-
|708
|数研出版
|化学基礎
|A5判
|-
|709
|数研出版
|高等学校 化学基礎
|B5判変型
|-
|710
|数研出版
|新編 化学基礎
|B5判
|-
|711
|第一学習社
|高等学校 化学基礎
|B5判変型
|-
|712
|第一学習社
|高等学校 化学基礎
|B5判
|}
===化学===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学 Vol.1 理論編
|B5判変型
|-
|702
|東京書籍
|化学 Vol.2 物質編
|B5判変型
|-
|703
|実教出版
|化学 academia
|A5判
|-
|704
|実教出版
|化学
|B5判
|-
|705
|啓林館
|高等学校 化学
|A5判
|-
|706
|数研出版
|化学
|A5判
|-
|707
|数研出版
|新編 化学
|B5判
|-
|708
|第一学習社
|高等学校 化学
|B5判変型
|}
===生物基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|生物基礎
|B5判変型
|-
|702
|東京書籍
|新編生物基礎
|B5判
|-
|703
|実教出版
|生物基礎
|B5判
|-
|704
|実教出版
|高校生物基礎
|B5判
|-
|705
|啓林館
|高等学校 生物基礎
|B5判変型
|-
|706
|啓林館
|i版 生物基礎
|AB判
|-
|707
|数研出版
|生物基礎
|A5判
|-
|708
|数研出版
|高等学校 生物基礎
|B5判変型
|-
|709
|数研出版
|新編 生物基礎
|B5判
|-
|710
|第一学習社
|高等学校 生物基礎
|B5判変型
|-
|711
|第一学習社
|高等学校 新生物基礎
|B5判
|}
===生物===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||生物||B5判変型
|-
|702||実教出版||生物||B5判
|-
|703||啓林館||高等学校 生物||B5判変型
|-
|704||数研出版||生物||B5判変型
|-
|705||第一学習社||高等学校 生物||B5判変型
|}
===地学基礎===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||地学基礎||B5判
|-
|702||実教出版||地学基礎||B5判
|-
|703||啓林館||高等学校 地学基礎||B5判変型
|-
|704||数研出版||高等学校 地学基礎||B5判変型
|-
|705||第一学習社||高等学校 地学基礎||B5判
|}
===地学===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||啓林館||高等学校 地学||A5判
|}
== 保健体育 ==
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||大修館書店||現代高等保健育||B5判
|-
|702||大修館書店||新高等保健体育||B5判変型
|-
|703||第一学習社||高等学校 保健体育 Textbook||B5判
|-
|704||第一学習社||高等学校 保健体育 Activity||B5判
|}
== 芸術 ==
=== 音楽Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅰ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽1 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA1 || A4判
|-
| 704 || 音楽之友社 || ON! 1 || A4判変型
|}
=== 音楽Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅱ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽2 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA2 || A4判
|-
| 704 || 音楽之友社 || ON! 2 || A4判変型
|}
=== 美術Ⅰ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 ||美術1 || A4判変型
|-
| 702 ||日本文教出版 ||高校生の美術1 ||A4判
|-
| 703 || 日本文教出版 ||高校美術 ||A4判変型
|}
=== 美術Ⅱ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 || 美術2 ||A4判変型
|-
| 702 || 日本文教出版 || 高校生の美術2 ||A4判
|}
=== 工芸Ⅰ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅰ||A4判
|}
=== 工芸Ⅱ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅱ||A4判
|}
=== 書道Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅰ || A4判
|-
| 702 || 教育図書 || 書Ⅰ || A4判
|-
| 703 || 教育図書 || 書Ⅰプライマリーブック || A4判
|-
| 704 || 教育出版 || 書道Ⅰ || A4判
|-
| 705 || 光村図書出版 || 書Ⅰ || A4判
|}
=== 書道Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅱ || A4判
|-
| 702 || 教育図書 || 書Ⅱ || A4判
|-
| 703 || 教育出版 || 書道Ⅱ || A4判
|-
| 704 || 光村図書出版 || 書Ⅱ || A4判
|}
== 外国語 ==
=== 英語コミュニケーションⅠ ===
=== 英語コミュニケーションⅡ ===
=== 論理・表現Ⅰ ===
=== 論理・表現Ⅱ ===
== 家庭 ==
=== 家庭基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭基礎 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭基礎365 || AB判
|-
| 703 || 教育図書 || 家庭基礎 つながる暮らし 共に創る未来 || B5判
|-
| 704 || 教育図書 || Survive!! 高等学校 家庭基礎 || AB判
|-
| 705 || 実教出版 || 家庭基礎 気づく力 築く未来 || AB判
|-
| 706 || 実教出版 || Agenda家庭基礎 || B5判
|-
| 707 || 実教出版 || 図説家庭基礎 || AB判
|-
| 708 || 開隆堂 || 家庭基礎 明日の生活を築く || AB判
|-
| 709 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭基礎』で生活をつくろう || A4判
|-
| 710 || 第一学習社 || 高等学校 家庭基礎 持続可能な未来をつくる || AB判
|}
=== 家庭総合 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭総合 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭総合365 || AB判
|-
| 703 || 実教出版 || 家庭総合 || AB判
|-
| 704 || 開隆堂 || 家庭総合 明日の生活を築く || AB判
|-
| 705 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭総合』で生活をつくろう || A4判
|-
| 706 || 第一学習社 || 高等学校 家庭総合 持続可能な未来をつくる || AB判
|}
== 情報 ==
=== 情報Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新編情報Ⅰ || B5判
|-
| 702 || 東京書籍 || 情報Ⅰ Step Forward! || B5判
|-
| 703 || 実教出版 || 高校情報Ⅰ Python || B5判
|-
| 704 || 実教出版 || 高校情報Ⅰ JavaScript || B5判
|-
| 705 || 実教出版 || 最新情報Ⅰ || B5判
|-
| 706 || 実教出版 || 図説情報Ⅰ || AB判
|-
| 707 || 開隆堂 || 実践 情報Ⅰ || B5判
|-
| 708 || 数研出版 || 高等学校 情報Ⅰ || B5判
|-
| 709 || 数研出版 || 情報Ⅰ Next || B5判
|-
| 710 || 日本文教出版 || 情報Ⅰ || B5判変型
|-
| 711 || 日本文教出版 || 情報Ⅰ図解と実習-図解編 || B5判変型
|-
| 712 || 日本文教出版 || 情報Ⅰ図解と実習-実習編 || B5判変型
|-
| 713 || 第一学習社 || 高等学校 情報Ⅰ || AB判
|}
=== 情報Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 情報Ⅱ || B5判
|-
| 702 || 実教出版 || 情報Ⅱ || B5判
|-
| 703 || 日本文教出版 || 情報Ⅱ || B5判変型
|}
== 理数 ==
=== 理数探究基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 啓林館 || 理数探究基礎 未来に向かって || A4判
|-
| 702 || 数研出版 || 理数探究基礎 || B5判
|}
== 農業 ==
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|実教出版
|農業と環境
|B5判
|-
|702
|実教出版
|農業と情報
|B5判
|-
|708
|実教出版
|草花
|B5判
|-
|710
|実教出版
|栽培と環境
|B5判
|-
|709
|実教出版
|農業機械
|B5判
|-
|703
|実教出版
|植物バイオテクノロジー
|B5判
|-
|704
|実教出版
|食品製造
|B5判
|-
|711
|実教出版
|生物活用
|B5判
|-
|705
|実教出版
|森林科学
|B5判
|-
|712
|実教出版
|森林経営
|
|-
|706
|実教出版
|農業土木設計
|B5判
|-
|713
|東京電機大学
|農業土木施工
|B5判
|-
|707
|実教出版
|造園計画
|B5判
|-
|714
|東京電機大学
|造園施工管理
|B5判
|}
== 工業 ==
== 商業 ==
== 水産 ==
== 家庭 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || ファッションデザイン || B5判
|-
| 702 || 教育図書 || フードデザイン Food Changes LIFE || AB判
|-
| 703 || 実教出版 || フードデザイン || AB判
|-
| 704 || 実教出版 || 生活産業情報 || B5判
|-
| 705 || 実教出版 || ファッション造形基礎 || B5判
|-
| 706 || 教育図書 || 保育基礎 ようこそ、ともに育ち合う保育の世界へ || AB判
|-
| 707 || 実教出版 || 保育基礎 || B5判
|-
| 708 || 実教出版 || 消費生活 || B5判
|-
| 709 || 実教出版 || 保育実践 || B5判
|-
| 710 || 実教出版 || 服飾文化 || B5判
|}
== 看護 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 基礎看護 || B5判
|}
== 情報 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 情報産業と社会 || B5判
|-
| 702 || 実教出版 || 情報の表現と管理 || B5判
|-
| 703 || 東京電機大学 || 情報システムのプログラミング || B5判
|-
| 704 || 実教出版 || 情報セキュリティ || B5判
|-
| 705 || 実教出版 || 情報デザイン || B5判
|-
| 706 || 実教出版 || ネットワークシステム || B5判
|-
| 707 || 実教出版 || データベース || B5判
|}
== 福祉 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 社会福祉基礎 || B5判
|-
| 702 || 実教出版 || 介護福祉基礎 || B5判
|-
| 703 || 実教出版 || 生活支援技術 || B5判
|-
| 704 || 実教出版 || こころとからだの理解 || B5判
|}
==脚注==
*[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
7h5p3eqrfr53lzebuonf1wrig4mtag7
205813
205797
2022-07-25T05:35:00Z
Kwawe
68789
/* 英語コミュニケーションⅠ */
wikitext
text/x-wiki
{{Pathnav|メインページ|[[小学校・中学校・高等学校の学習]]>[[高等学校の学習]]>[[検定教科書]]|frame=1}}
このページでは、'''高等学校の教科書番号'''について説明します。教科書番号については、[[../|この上層ページ]]をご覧ください。
本内容は令和5年度以降の教科書目録をまとめています。
※以下、このページは新高校1年生から使う教科書を掲載しています。旧課程(現高校2~3年生)の教科書はこのページに掲載しておりません。
==国語==
※国語は本を読ますための性格なのか、A5版がほとんどです。
===現代の国語===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編現代の国語||A5判
|-
|702||東京書籍||精選現代の国語||A5判
|-
|703||東京書籍||現代の国語||A5判
|-
|704||三省堂||精選 現代の国語||A5判
|-
|705||三省堂||新 現代の国語||A5判
|-
|706||大修館書店||現代の国語||A5判
|-
|707||大修館書店||新編 現代の国語||B5判
|-
|708||数研出版||現代の国語||A5判
|-
|709||数研出版||高等学校 現代の国語||A5判
|-
|710||数研出版||新編 現代の国語||A5判
|-
|711||明治書院||精選 現代の国語||A5判
|-
|712||筑摩書房||現代の国語||A5判
|-
|713||第一学習社||高等学校 現代の国語||A5判
|-
|714||第一学習社||高等学校 精選現代の国語||A5判
|-
|715||第一学習社||高等学校 標準現代の国語||A5判
|-
|716||第一学習社||高等学校 新編現代の国語||B5判
|-
|717||桐原書店||探求 現代の国語||A5判
|-
|}
===言語文化===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編言語文化||A5判
|-
|702||東京書籍||精選言語文化||A5判
|-
|703||三省堂||精選 言語文化||A5判
|-
|704||三省堂||新 言語文化||A5判
|-
|705||大修館書店||言語文化||A5判
|-
|706||大修館書店||新編 言語文化||B5判
|-
|708||数研出版||高等学校 言語文化||A5判
|-
|709||数研出版||新編 言語文化||A5判
|-
|710||文英堂||言語文化||A5判
|-
|711||明治書院||精選言語文化||A5判
|-
|712||筑摩書房||言語文化||A5判
|-
|713||第一学習社||高等学校 言語文化||A5判
|-
|714||第一学習社||高等学校 精選言語文化||A5判
|-
|715||第一学習社||高等学校 標準言語文化||A5判
|-
|716||第一学習社||高等学校 新編言語文化||B5判
|-
|717||桐原書店||探求 言語文化||A5判
|}
===論理国語 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 論理国語 || A5判
|-
| 702 || 東京書籍 || 精選論理国語 || A5判
|-
| 703 || 三省堂 || 精選 論理国語 || A5判
|-
| 704 || 三省堂 || 新 論理国語 || A5判
|-
| 705 || 大修館書店 || |論理国語 || A5判
|-
| 706 || 大修館書店 || 新編 論理国語 || A5判
|-
| 707 || 数研出版 || 精選 論理国語 || A5判
|-
| 708 || 数研出版 || 論理国語 || A5判
|-
| 709 || 明治書院 || 精選 論理国語 || A5判
|-
| 710 || 筑摩書房 || 論理国語 || A5判
|-
| 711 || 第一学習社 || 高等学校 論理国語 || A5判
|-
| 712|| 第一学習社 || 高等学校 標準論理国語 || A5判
|-
| 713 || 桐原書店 || 探求 論理国語 || A5判
|}
===文学国語===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 文学国語 || A5判
|-
| 702 || 三省堂 || 精選 文学国語 || A5判
|-
| 703 || 三省堂 || 新 文学国語 || A5判
|-
| 704 || 大修館書店 || |文学国語 || A5判
|-
| 705 || 大修館書店 || 新編 文学国語 || A5判
|-
| 706 || 数研出版 || 文学国語 || A5判
|-
| 707 || 明治書院 || 精選 文学国語 || A5判
|-
| 708 || 筑摩書房 || 文学国語 || A5判
|-
| 709 || 第一学習社 || 高等学校 文学国語 || A5判
|-
| 710 || 第一学習社 || 高等学校 標準文学国語 || A5判
|-
| 711 || 桐原書店 || 探求 文学国語 || A5判
|}
===国語表現===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 大修館書店 || 国語表現 || B5判
|}
===古典探究 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社!! 教科書名!! 判型
|-
| 701 || 東京書籍 ||新編古典探究 || A5判
|-
| 702 || 東京書籍 ||精選古典探究 古文編 || A5判
|-
| 703 || 東京書籍 ||精選古典探究 漢文編 || A5判
|-
| 704 || 三省堂 ||精選 古典探究 古文編 || A5判
|-
| 705 || 三省堂 ||精選 古典探究 漢文編 || A5判
|-
| 706 || 大修館書店 ||古典探究 古文編 || A5判
|-
| 707 || 大修館書店 ||古典探究 漢文編 || A5判
|-
| 708 || 大修館書店 ||精選 古典探究 || A5判
|-
| 709 || 数研出版 ||古典探究 古文編 || A5判
|-
| 710 || 数研出版 ||古典探究 漢文編 || A5判
|-
| 711 || 数研出版 ||高等学校 古典探究 || A5判
|-
| 712 || 文英堂 ||古典探究 || A5判
|-
| 713 || 明治書院 ||精選 古典探究 古文編|| A5判
|-
| 714 || 明治書院 ||精選 古典探究 漢文編 || A5判
|-
| 715 || 筑摩書房 ||古典探究 古文編 || A5判
|-
| 716 || 筑摩書房 ||古典探究 漢文編 || A5判
|-
| 717 || 第一学習社 ||高等学校 古典探究 古文編 || A5判
|-
| 718 || 第一学習社 || 高等学校 古典探究 漢文編 || A5判
|-
| 719 || 第一学習社 || 高等学校 精選古典探究 || A5判
|-
| 720 || 第一学習社 || 高等学校 標準古典探究 || A5判
|-
| 721 || 桐原書店 || 探求 古典探究 古文編 || A5判
|-
| 722 || 桐原書店 || 探求 古典探究 漢文編 || A5判
|}
==地理歴史==
===地理総合===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 地理総合 || AB判
|-
| 702 || 実教出版 || 地理総合 || AB判
|-
| 703 || 帝国書院 || 高等学校 地理総合 || AB判
|-
| 704 || 二宮書店 || 地理総合 世界に学び地域へつなぐ || B5判
|-
| 705 || 二宮書店 || わたしたちの地理総合 世界から日本へ || AB判
|-
| 706 || 第一学習社 || 高等学校 地理総合 世界を学び、地域をつくる || AB判
|-
| 707 || 帝国書院 || 高校生の地理総合 || AB判
|}
===地理探究===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
| 701 ||東京書籍||地理探究||AB判
|-
|702||帝国書院||新詳地理探究||B5判
|-
|703||二宮書店|| 地理探究||B5判
|}
===歴史総合===
{| class="wikitable sortable"
|-
! 番号!! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新選歴史総合 || AB判
|-
| 702 || 東京書籍 || 詳解歴史総合 || B5判
|-
| 703 || 実教出版 || 詳述歴史総合 || B5判
|-
| 704 || 実教出版 || 歴史総合 || AB判
|-
| 705 || 清水書院 || 私たちの歴史総合 || A4判
|-
| 706 || 帝国書院 || 明解 歴史総合 || AB判
|-
| 707 || 山川出版社 || 歴史総合 近代から現代へ || B5判
|-
| 708 || 山川出版社 || 現代の歴史総合 みる・読みとく・考える || AB判
|-
| 709 || 山川出版社 || わたしたちの歴史 日本から世界へ || AB判
|-
| 710 || 第一学習社 || 高等学校 歴史総合 || AB判
|-
| 711 || 第一学習社 || 高等学校 新歴史総合 過去との対話、つなぐ未来 || AB判
|-
| 712 || 明成社 || 私たちの歴史総合 || B5判
|}
===日本史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 日本史探究 || B5判
|-
| 702 || 実教出版 || 日本史探究 || B5判変型
|-
| 703 || 実教出版 ||精選日本史探究 今につなぐ 未来をえがく || AB判
|-
| 704 || 清水書院 || 高等学校 日本史探究 || B5判
|-
| 705 || 山川出版社 || 詳説日本史 || B5判変型
|-
| 706 || 山川出版社 || 高校日本史|| B5判
|-
| 707 || 第一学習社 || 高等学校 日本史探究 || B5判
|}
===世界史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 世界史探究 || B5判
|-
| 702 || 実教出版 || 世界史探究 || B5判変型
|-
| 703 || 帝国書院 || 新詳世界史探究 || B5判
|-
| 704 || 山川出版社 || 詳説世界史 || B5判変型
|-
| 705 || 山川出版社 || 高校世界史 || B5判
|-
| 706 || 山川出版社 || 新世界史 || B5判変型
|-
| 707 || 第一学習社 || 高等学校 世界史探究 || B5判
|}
===地図===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新高等地図 || A4判
|-
| 702 || 帝国書院 || 新詳高等地図 || AB判
|-
| 703 || 帝国書院 || 標準高等地図 || A4判
|-
| 704 || 二宮書店 || 高等地図帳 || B5判
|-
| 705 || 二宮書店 || 詳解現代地図 最新版 || AB判
|-
| 706 || 二宮書店 || 基本地図帳 || A4判
|-
| 707 || 二宮書店 || コンパクト地理総合地図 || AB判変型
|}
==公民==
===公共===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||公共||AB判
|-
|702||教育図書||公共||B5判
|-
|703||実教出版||詳述公共||A5判
|-
|704||実教出版||公共||B5判
|-
|705||清水書院||高等学校 公共||B5判
|-
|706||清水書院||私たちの公共||AB判
|-
|707||帝国書院||高等学校 公共||AB判
|-
|708||数研出版||公共(令和4年度)||
|-
|709||数研出版||高等学校 公共 これからの社会について考える||AB判
|-
|710||第一学習社||高等学校 公共||B5判
|-
|711||第一学習社||高等学校 新公共||AB判
|-
|712||東京法令出版||公共||B5判
|-
|713||数研出版||新版 公共(令和5年度)||B5判
|}
===倫理===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 倫理 || B5判変型
|-
| 702 || 実教出版 || 詳述倫理 || A5判
|-
| 703 || 清水書院 || 高等学校 新倫理 || A5判
|-
| 704 || 数研出版 || 倫理 || A5判
|-
| 705 || 第一学習社 || 高等学校 倫理 || B5判
|}
===政治・経済===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
|701||東京書籍||政治・経済||B5判変型
|-
|702||実教出版||詳述政治・経済||A5判
|-
|703||実教出版||最新政治・経済||B5判
|-
|704||清水書院||高等学校 政治・経済||A5判
|-
|705||数研出版||政治・経済||A5判
|-
|706||第一学習社||高等学校 政治・経済||B5判
|}
==数学==
===数学Ⅰ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅰ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅰ Standard || A5判
|-
| 703 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学Ⅰ || B5判
|-
| 705 || 東京書籍 || 新数学Ⅰ 解答編 || B5判
|-
| 706 || 実教出版 || 数学Ⅰ Progress || A5判
|-
| 707 || 実教出版 || 新編数学Ⅰ || A5判
|-
| 708|| 実教出版 || 高校数学Ⅰ || B5判
|-
| 709 || 啓林館 || 数学Ⅰ || A5判
|-
| 710 || 啓林館 || 新編数学Ⅰ || A5判
|-
| 711 || 啓林館 || 深進数学Ⅰ || A5判
|-
| 712 || 数研出版 || 数学Ⅰ || A5判
|-
| 713 || 数研出版 || 高等学校 数学Ⅰ || A5判
|-
| 714 || 数研出版 || 新編 数学Ⅰ || A5判
|-
| 715 || 数研出版 || 最新 数学Ⅰ || A5判
|-
| 716 || 数研出版 || 新 高校の数学Ⅰ || B5判
|-
| 717 ||数研出版 || NEXT 数学Ⅰ || A5判
|-
| 718 || 第一学習社|| 新編数学Ⅰ || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Ⅰサポートブック || B5判変型版
|}
===数学Ⅱ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅱ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅱ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅱ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅱ || A5判
|-
| 705|| 実教出版 || 高校数学Ⅱ || B5判
|-
| 706 || 啓林館 || 数学Ⅱ || A5判
|-
| 707 || 啓林館 || 新編数学Ⅱ || A5判
|-
| 708 || 啓林館 || 深進数学Ⅱ || A5判
|-
| 709 || 数研出版 || 数学Ⅱ || A5判
|-
| 710 || 数研出版 || 高等学校 数学Ⅱ || A5判
|-
| 711 || 数研出版 || 新編 数学Ⅱ || A5判
|-
| 712 || 数研出版 || 最新 数学Ⅱ || A5判
|-
| 713 ||数研出版 || NEXT 数学Ⅱ || A5判
|-
| 714 || 第一学習社|| 新編数学Ⅱ || B5判変型版
|-
| 715 || 第一学習社 || 新編数学Ⅱサポートブック || B5判変型版
|-
| 716 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 717 || 東京書籍 || 新数学Ⅱ || B5判
|-
| 718 || 東京書籍 || 新数学Ⅱ 解答編 || B5判
|-
| 719 || 数研出版 || 新 高校の数学Ⅱ || B5判
|}
===数学Ⅲ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅲ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅲ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅲ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅲ || A5判
|-
| 705 || 啓林館 || 数学Ⅲ || A5判
|-
| 706 || 啓林館 || 新編数学Ⅲ || A5判
|-
| 707 || 啓林館 || 深進数学Ⅲ || A5判
|-
| 708 || 数研出版 || 数学Ⅲ || A5判
|-
| 709 || 数研出版 || 高等学校 数学Ⅲ || A5判
|-
| 710 || 数研出版 || 新編 数学Ⅲ || A5判
|-
| 711 || 数研出版 || 最新 数学Ⅲ || A5判
|-
| 712 ||数研出版 || NEXT 数学Ⅲ || A5判
|}
===数学A===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学A Advanced || A5判
|-
| 702 || 東京書籍 || 数学A Standard || A5判
|-
| 703 || 東京書籍 || 数学A Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学A || B5判
|-
| 705 || 東京書籍 || 新数学A 解答編 || B5判
|-
| 706 || 実教出版 || 数学A Progress || A5判
|-
| 707 || 実教出版 || 新編数学A || A5判
|-
| 708|| 実教出版 || 高校数学A || B5判
|-
| 709 || 啓林館 || 数学A || A5判
|-
| 710 || 啓林館 || 新編数学A || A5判
|-
| 711 || 啓林館 || 深進数学A || A5判
|-
| 712 || 数研出版 || 数学A || A5判
|-
| 713 || 数研出版 || 高等学校 数学A || A5判
|-
| 714 || 数研出版 || 新編 数学A || A5判
|-
| 715 || 数研出版 || 最新 数学A || A5判
|-
| 716 || 数研出版 || 新 高校の数学A || B5判
|-
| 717 ||数研出版 || NEXT 数学A || A5判
|-
| 718 || 第一学習社|| 新編数学A || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Aサポートブック || B5判変型版
|}
===数学B===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学B Advanced || A5判
|-
| 702 || 東京書籍 || 数学B Standard || A5判
|-
| 703 || 東京書籍 || 数学B Essence || B5判変型版
|-
| 704 || 実教出版 || 数学B Progress || A5判
|-
| 705 || 実教出版 || 新編数学B || A5判
|-
| 706|| 実教出版 || 高校数学B || B5判
|-
| 707 || 啓林館 || 数学B || A5判
|-
| 708 || 啓林館 || 新編数学B || A5判
|-
| 709 || 啓林館 || 深進数学B || A5判
|-
| 710 || 数研出版 || 数学B || A5判
|-
| 711 || 数研出版 || 高等学校 数学B || A5判
|-
| 712 || 数研出版 || 新編 数学B || A5判
|-
| 713 || 数研出版 || 最新 数学B || A5判
|-
| 714 || 数研出版 || 新 高校の数学B || B5判
|-
| 715 ||数研出版 || NEXT 数学B || A5判
|-
| 716 || 第一学習社|| 新編数学B || B5判変型版
|}
===数学C===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学C Advanced || A5判
|-
| 702 || 東京書籍 || 数学C Standard || A5判
|-
| 703 || 実教出版 || 数学C Progress || A5判
|-
| 704 || 実教出版 || 新編数学C || A5判
|-
| 705 || 啓林館 || 数学C || A5判
|-
| 706 || 啓林館 || 新編数学C || A5判
|-
| 707 || 啓林館 || 深進数学C || A5判
|-
| 708 || 数研出版 || 数学C || A5判
|-
| 709 || 数研出版 || 高等学校 数学C || A5判
|-
| 710 || 数研出版 || 新編 数学C || A5判
|-
| 711 || 数研出版 || 最新 数学C || A5判
|-
| 712 || 数研出版 || NEXT 数学C || A5判
|-
| 713 || 第一学習社 || 新編数学C || B5判変型
|}
==理科==
===科学と人間生活===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 科学と人間生活 || B5判変型
|-
| 702 || 実教出版 || 科学と人間生活 || B5判
|-
| 703 || 啓林館 || 高等学校 科学と人間生活 || B5判
|-
| 704 || 数研出版 || 科学と人間生活 || AB判
|-
| 705 || 第一学習社 || 高等学校 科学と人間生活 || B5判
|}
===物理基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|物理基礎
|B5判変型
|-
|702
|東京書籍
|新編物理基礎
|B5判
|-
|703
|実教出版
|物理基礎
|B5判
|-
|704
|実教出版
|高校物理基礎
|B5判
|-
|705
|啓林館
|高等学校 物理基礎
|A5判
|-
|706
|啓林館
|高等学校 考える物理基礎
|B5判
|-
|707
|数研出版
|物理基礎
|A5判
|-
|708
|数研出版
|新編 物理基礎
|B5判
|-
|709
|第一学習社
|高等学校 物理基礎
|B5判変型
|-
|710
|第一学習社
|高等学校 新物理基礎
|B5判
|}
===物理===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|物理
|B5判変型
|-
|702
|実教出版
|物理
|B5判
|-
|703
|啓林館
|高等学校 物理
|A5判
|-
|704
|啓林館
|高等学校 総合物理1 様々な運動 熱 波
|A5判
|-
|705
|啓林館
|高等学校 総合物理2 電気と磁気 原子・分子の世界
|A5判
|-
|706
|数研出版
|物理
|A5判
|-
|707
|数研出版
|総合物理1 力と運動・熱
|A5判
|-
|708
|数研出版
|総合物理2 波・電気と磁気・原子
|A5判
|-
|709
|第一学習社
|高等学校 物理
|B5判変型
|}
===化学基礎===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学基礎
|B5判変型
|-
|702
|東京書籍
|新編化学基礎
|B5判
|-
|703
|実教出版
|化学基礎 academia
|A5判
|-
|704
|実教出版
|化学基礎
|B5判
|-
|705
|実教出版
|高校化学基礎
|B5判
|-
|706
|啓林館
|高等学校 化学基礎
|A5判
|-
|707
|啓林館
|i版 化学基礎
|AB判
|-
|708
|数研出版
|化学基礎
|A5判
|-
|709
|数研出版
|高等学校 化学基礎
|B5判変型
|-
|710
|数研出版
|新編 化学基礎
|B5判
|-
|711
|第一学習社
|高等学校 化学基礎
|B5判変型
|-
|712
|第一学習社
|高等学校 化学基礎
|B5判
|}
===化学===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学 Vol.1 理論編
|B5判変型
|-
|702
|東京書籍
|化学 Vol.2 物質編
|B5判変型
|-
|703
|実教出版
|化学 academia
|A5判
|-
|704
|実教出版
|化学
|B5判
|-
|705
|啓林館
|高等学校 化学
|A5判
|-
|706
|数研出版
|化学
|A5判
|-
|707
|数研出版
|新編 化学
|B5判
|-
|708
|第一学習社
|高等学校 化学
|B5判変型
|}
===生物基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|生物基礎
|B5判変型
|-
|702
|東京書籍
|新編生物基礎
|B5判
|-
|703
|実教出版
|生物基礎
|B5判
|-
|704
|実教出版
|高校生物基礎
|B5判
|-
|705
|啓林館
|高等学校 生物基礎
|B5判変型
|-
|706
|啓林館
|i版 生物基礎
|AB判
|-
|707
|数研出版
|生物基礎
|A5判
|-
|708
|数研出版
|高等学校 生物基礎
|B5判変型
|-
|709
|数研出版
|新編 生物基礎
|B5判
|-
|710
|第一学習社
|高等学校 生物基礎
|B5判変型
|-
|711
|第一学習社
|高等学校 新生物基礎
|B5判
|}
===生物===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||生物||B5判変型
|-
|702||実教出版||生物||B5判
|-
|703||啓林館||高等学校 生物||B5判変型
|-
|704||数研出版||生物||B5判変型
|-
|705||第一学習社||高等学校 生物||B5判変型
|}
===地学基礎===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||地学基礎||B5判
|-
|702||実教出版||地学基礎||B5判
|-
|703||啓林館||高等学校 地学基礎||B5判変型
|-
|704||数研出版||高等学校 地学基礎||B5判変型
|-
|705||第一学習社||高等学校 地学基礎||B5判
|}
===地学===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||啓林館||高等学校 地学||A5判
|}
== 保健体育 ==
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||大修館書店||現代高等保健育||B5判
|-
|702||大修館書店||新高等保健体育||B5判変型
|-
|703||第一学習社||高等学校 保健体育 Textbook||B5判
|-
|704||第一学習社||高等学校 保健体育 Activity||B5判
|}
== 芸術 ==
=== 音楽Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅰ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽1 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA1 || A4判
|-
| 704 || 音楽之友社 || ON! 1 || A4判変型
|}
=== 音楽Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅱ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽2 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA2 || A4判
|-
| 704 || 音楽之友社 || ON! 2 || A4判変型
|}
=== 美術Ⅰ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 ||美術1 || A4判変型
|-
| 702 ||日本文教出版 ||高校生の美術1 ||A4判
|-
| 703 || 日本文教出版 ||高校美術 ||A4判変型
|}
=== 美術Ⅱ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 || 美術2 ||A4判変型
|-
| 702 || 日本文教出版 || 高校生の美術2 ||A4判
|}
=== 工芸Ⅰ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅰ||A4判
|}
=== 工芸Ⅱ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅱ||A4判
|}
=== 書道Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅰ || A4判
|-
| 702 || 教育図書 || 書Ⅰ || A4判
|-
| 703 || 教育図書 || 書Ⅰプライマリーブック || A4判
|-
| 704 || 教育出版 || 書道Ⅰ || A4判
|-
| 705 || 光村図書出版 || 書Ⅰ || A4判
|}
=== 書道Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅱ || A4判
|-
| 702 || 教育図書 || 書Ⅱ || A4判
|-
| 703 || 教育出版 || 書道Ⅱ || A4判
|-
| 704 || 光村図書出版 || 書Ⅱ || A4判
|}
== 外国語 ==
=== 英語コミュニケーションⅠ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅰ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅠ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅠ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅠ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅠ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅠ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅠ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅠ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅠ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅰ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅰ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅰ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅰ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅰ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅰ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅰ
|AB判
|-
|719
|文英堂
|Grove English CommunicationⅠ
|B5判
|-
|720
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅰ
|B5判
|-
|721
|第一学習社
|CREATIVE English Communication Ⅰ
|B5判
|-
|722
|第一学習社
|Vivid English Communication Ⅰ
|B5判
|-
|723
|桐原書店
|Heartening English Communication Ⅰ
|B5判
|-
|724
|いいずな書店
|New Rays English Communication Ⅰ
|B5判変型
|-
|725
|Cambridge University Press & Assessment
|Cambridge Experience 1
|A4判
|}
=== 英語コミュニケーションⅡ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅱ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅡ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅡ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅡ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅡ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅡ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅡ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅡ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅡ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅱ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅱ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅱ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅱ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅱ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅱ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅱ
|AB判
|-
|719
|文英堂
|Grove English CommunicationⅡ
|B5判
|-
|720
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅱ
|B5判
|-
|721
|第一学習社
|CREATIVE English Communication Ⅱ
|B5判
|-
|722
|第一学習社
|Vivid English Communication Ⅱ
|B5判
|-
|723
|桐原書店
|Heartening English Communication Ⅱ
|B5判
|-
|724
|いいずな書店
|New Rays English Communication Ⅱ
|B5判変型
|-
|725
|Cambridge University Press & Assessment
|Cambridge Experience 1
|A4判
|}
=== 論理・表現Ⅰ ===
=== 論理・表現Ⅱ ===
== 家庭 ==
=== 家庭基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭基礎 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭基礎365 || AB判
|-
| 703 || 教育図書 || 家庭基礎 つながる暮らし 共に創る未来 || B5判
|-
| 704 || 教育図書 || Survive!! 高等学校 家庭基礎 || AB判
|-
| 705 || 実教出版 || 家庭基礎 気づく力 築く未来 || AB判
|-
| 706 || 実教出版 || Agenda家庭基礎 || B5判
|-
| 707 || 実教出版 || 図説家庭基礎 || AB判
|-
| 708 || 開隆堂 || 家庭基礎 明日の生活を築く || AB判
|-
| 709 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭基礎』で生活をつくろう || A4判
|-
| 710 || 第一学習社 || 高等学校 家庭基礎 持続可能な未来をつくる || AB判
|}
=== 家庭総合 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭総合 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭総合365 || AB判
|-
| 703 || 実教出版 || 家庭総合 || AB判
|-
| 704 || 開隆堂 || 家庭総合 明日の生活を築く || AB判
|-
| 705 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭総合』で生活をつくろう || A4判
|-
| 706 || 第一学習社 || 高等学校 家庭総合 持続可能な未来をつくる || AB判
|}
== 情報 ==
=== 情報Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新編情報Ⅰ || B5判
|-
| 702 || 東京書籍 || 情報Ⅰ Step Forward! || B5判
|-
| 703 || 実教出版 || 高校情報Ⅰ Python || B5判
|-
| 704 || 実教出版 || 高校情報Ⅰ JavaScript || B5判
|-
| 705 || 実教出版 || 最新情報Ⅰ || B5判
|-
| 706 || 実教出版 || 図説情報Ⅰ || AB判
|-
| 707 || 開隆堂 || 実践 情報Ⅰ || B5判
|-
| 708 || 数研出版 || 高等学校 情報Ⅰ || B5判
|-
| 709 || 数研出版 || 情報Ⅰ Next || B5判
|-
| 710 || 日本文教出版 || 情報Ⅰ || B5判変型
|-
| 711 || 日本文教出版 || 情報Ⅰ図解と実習-図解編 || B5判変型
|-
| 712 || 日本文教出版 || 情報Ⅰ図解と実習-実習編 || B5判変型
|-
| 713 || 第一学習社 || 高等学校 情報Ⅰ || AB判
|}
=== 情報Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 情報Ⅱ || B5判
|-
| 702 || 実教出版 || 情報Ⅱ || B5判
|-
| 703 || 日本文教出版 || 情報Ⅱ || B5判変型
|}
== 理数 ==
=== 理数探究基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 啓林館 || 理数探究基礎 未来に向かって || A4判
|-
| 702 || 数研出版 || 理数探究基礎 || B5判
|}
== 農業 ==
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|実教出版
|農業と環境
|B5判
|-
|702
|実教出版
|農業と情報
|B5判
|-
|708
|実教出版
|草花
|B5判
|-
|710
|実教出版
|栽培と環境
|B5判
|-
|709
|実教出版
|農業機械
|B5判
|-
|703
|実教出版
|植物バイオテクノロジー
|B5判
|-
|704
|実教出版
|食品製造
|B5判
|-
|711
|実教出版
|生物活用
|B5判
|-
|705
|実教出版
|森林科学
|B5判
|-
|712
|実教出版
|森林経営
|
|-
|706
|実教出版
|農業土木設計
|B5判
|-
|713
|東京電機大学
|農業土木施工
|B5判
|-
|707
|実教出版
|造園計画
|B5判
|-
|714
|東京電機大学
|造園施工管理
|B5判
|}
== 工業 ==
== 商業 ==
== 水産 ==
== 家庭 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || ファッションデザイン || B5判
|-
| 702 || 教育図書 || フードデザイン Food Changes LIFE || AB判
|-
| 703 || 実教出版 || フードデザイン || AB判
|-
| 704 || 実教出版 || 生活産業情報 || B5判
|-
| 705 || 実教出版 || ファッション造形基礎 || B5判
|-
| 706 || 教育図書 || 保育基礎 ようこそ、ともに育ち合う保育の世界へ || AB判
|-
| 707 || 実教出版 || 保育基礎 || B5判
|-
| 708 || 実教出版 || 消費生活 || B5判
|-
| 709 || 実教出版 || 保育実践 || B5判
|-
| 710 || 実教出版 || 服飾文化 || B5判
|}
== 看護 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 基礎看護 || B5判
|}
== 情報 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 情報産業と社会 || B5判
|-
| 702 || 実教出版 || 情報の表現と管理 || B5判
|-
| 703 || 東京電機大学 || 情報システムのプログラミング || B5判
|-
| 704 || 実教出版 || 情報セキュリティ || B5判
|-
| 705 || 実教出版 || 情報デザイン || B5判
|-
| 706 || 実教出版 || ネットワークシステム || B5判
|-
| 707 || 実教出版 || データベース || B5判
|}
== 福祉 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 社会福祉基礎 || B5判
|-
| 702 || 実教出版 || 介護福祉基礎 || B5判
|-
| 703 || 実教出版 || 生活支援技術 || B5判
|-
| 704 || 実教出版 || こころとからだの理解 || B5判
|}
==脚注==
*[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
m33x85xys84b2k7kujllcs9btpjsyg6
205814
205813
2022-07-25T05:36:40Z
Kwawe
68789
/* 英語コミュニケーションⅡ */
wikitext
text/x-wiki
{{Pathnav|メインページ|[[小学校・中学校・高等学校の学習]]>[[高等学校の学習]]>[[検定教科書]]|frame=1}}
このページでは、'''高等学校の教科書番号'''について説明します。教科書番号については、[[../|この上層ページ]]をご覧ください。
本内容は令和5年度以降の教科書目録をまとめています。
※以下、このページは新高校1年生から使う教科書を掲載しています。旧課程(現高校2~3年生)の教科書はこのページに掲載しておりません。
==国語==
※国語は本を読ますための性格なのか、A5版がほとんどです。
===現代の国語===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編現代の国語||A5判
|-
|702||東京書籍||精選現代の国語||A5判
|-
|703||東京書籍||現代の国語||A5判
|-
|704||三省堂||精選 現代の国語||A5判
|-
|705||三省堂||新 現代の国語||A5判
|-
|706||大修館書店||現代の国語||A5判
|-
|707||大修館書店||新編 現代の国語||B5判
|-
|708||数研出版||現代の国語||A5判
|-
|709||数研出版||高等学校 現代の国語||A5判
|-
|710||数研出版||新編 現代の国語||A5判
|-
|711||明治書院||精選 現代の国語||A5判
|-
|712||筑摩書房||現代の国語||A5判
|-
|713||第一学習社||高等学校 現代の国語||A5判
|-
|714||第一学習社||高等学校 精選現代の国語||A5判
|-
|715||第一学習社||高等学校 標準現代の国語||A5判
|-
|716||第一学習社||高等学校 新編現代の国語||B5判
|-
|717||桐原書店||探求 現代の国語||A5判
|-
|}
===言語文化===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編言語文化||A5判
|-
|702||東京書籍||精選言語文化||A5判
|-
|703||三省堂||精選 言語文化||A5判
|-
|704||三省堂||新 言語文化||A5判
|-
|705||大修館書店||言語文化||A5判
|-
|706||大修館書店||新編 言語文化||B5判
|-
|708||数研出版||高等学校 言語文化||A5判
|-
|709||数研出版||新編 言語文化||A5判
|-
|710||文英堂||言語文化||A5判
|-
|711||明治書院||精選言語文化||A5判
|-
|712||筑摩書房||言語文化||A5判
|-
|713||第一学習社||高等学校 言語文化||A5判
|-
|714||第一学習社||高等学校 精選言語文化||A5判
|-
|715||第一学習社||高等学校 標準言語文化||A5判
|-
|716||第一学習社||高等学校 新編言語文化||B5判
|-
|717||桐原書店||探求 言語文化||A5判
|}
===論理国語 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 論理国語 || A5判
|-
| 702 || 東京書籍 || 精選論理国語 || A5判
|-
| 703 || 三省堂 || 精選 論理国語 || A5判
|-
| 704 || 三省堂 || 新 論理国語 || A5判
|-
| 705 || 大修館書店 || |論理国語 || A5判
|-
| 706 || 大修館書店 || 新編 論理国語 || A5判
|-
| 707 || 数研出版 || 精選 論理国語 || A5判
|-
| 708 || 数研出版 || 論理国語 || A5判
|-
| 709 || 明治書院 || 精選 論理国語 || A5判
|-
| 710 || 筑摩書房 || 論理国語 || A5判
|-
| 711 || 第一学習社 || 高等学校 論理国語 || A5判
|-
| 712|| 第一学習社 || 高等学校 標準論理国語 || A5判
|-
| 713 || 桐原書店 || 探求 論理国語 || A5判
|}
===文学国語===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 文学国語 || A5判
|-
| 702 || 三省堂 || 精選 文学国語 || A5判
|-
| 703 || 三省堂 || 新 文学国語 || A5判
|-
| 704 || 大修館書店 || |文学国語 || A5判
|-
| 705 || 大修館書店 || 新編 文学国語 || A5判
|-
| 706 || 数研出版 || 文学国語 || A5判
|-
| 707 || 明治書院 || 精選 文学国語 || A5判
|-
| 708 || 筑摩書房 || 文学国語 || A5判
|-
| 709 || 第一学習社 || 高等学校 文学国語 || A5判
|-
| 710 || 第一学習社 || 高等学校 標準文学国語 || A5判
|-
| 711 || 桐原書店 || 探求 文学国語 || A5判
|}
===国語表現===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 大修館書店 || 国語表現 || B5判
|}
===古典探究 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社!! 教科書名!! 判型
|-
| 701 || 東京書籍 ||新編古典探究 || A5判
|-
| 702 || 東京書籍 ||精選古典探究 古文編 || A5判
|-
| 703 || 東京書籍 ||精選古典探究 漢文編 || A5判
|-
| 704 || 三省堂 ||精選 古典探究 古文編 || A5判
|-
| 705 || 三省堂 ||精選 古典探究 漢文編 || A5判
|-
| 706 || 大修館書店 ||古典探究 古文編 || A5判
|-
| 707 || 大修館書店 ||古典探究 漢文編 || A5判
|-
| 708 || 大修館書店 ||精選 古典探究 || A5判
|-
| 709 || 数研出版 ||古典探究 古文編 || A5判
|-
| 710 || 数研出版 ||古典探究 漢文編 || A5判
|-
| 711 || 数研出版 ||高等学校 古典探究 || A5判
|-
| 712 || 文英堂 ||古典探究 || A5判
|-
| 713 || 明治書院 ||精選 古典探究 古文編|| A5判
|-
| 714 || 明治書院 ||精選 古典探究 漢文編 || A5判
|-
| 715 || 筑摩書房 ||古典探究 古文編 || A5判
|-
| 716 || 筑摩書房 ||古典探究 漢文編 || A5判
|-
| 717 || 第一学習社 ||高等学校 古典探究 古文編 || A5判
|-
| 718 || 第一学習社 || 高等学校 古典探究 漢文編 || A5判
|-
| 719 || 第一学習社 || 高等学校 精選古典探究 || A5判
|-
| 720 || 第一学習社 || 高等学校 標準古典探究 || A5判
|-
| 721 || 桐原書店 || 探求 古典探究 古文編 || A5判
|-
| 722 || 桐原書店 || 探求 古典探究 漢文編 || A5判
|}
==地理歴史==
===地理総合===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 地理総合 || AB判
|-
| 702 || 実教出版 || 地理総合 || AB判
|-
| 703 || 帝国書院 || 高等学校 地理総合 || AB判
|-
| 704 || 二宮書店 || 地理総合 世界に学び地域へつなぐ || B5判
|-
| 705 || 二宮書店 || わたしたちの地理総合 世界から日本へ || AB判
|-
| 706 || 第一学習社 || 高等学校 地理総合 世界を学び、地域をつくる || AB判
|-
| 707 || 帝国書院 || 高校生の地理総合 || AB判
|}
===地理探究===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
| 701 ||東京書籍||地理探究||AB判
|-
|702||帝国書院||新詳地理探究||B5判
|-
|703||二宮書店|| 地理探究||B5判
|}
===歴史総合===
{| class="wikitable sortable"
|-
! 番号!! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新選歴史総合 || AB判
|-
| 702 || 東京書籍 || 詳解歴史総合 || B5判
|-
| 703 || 実教出版 || 詳述歴史総合 || B5判
|-
| 704 || 実教出版 || 歴史総合 || AB判
|-
| 705 || 清水書院 || 私たちの歴史総合 || A4判
|-
| 706 || 帝国書院 || 明解 歴史総合 || AB判
|-
| 707 || 山川出版社 || 歴史総合 近代から現代へ || B5判
|-
| 708 || 山川出版社 || 現代の歴史総合 みる・読みとく・考える || AB判
|-
| 709 || 山川出版社 || わたしたちの歴史 日本から世界へ || AB判
|-
| 710 || 第一学習社 || 高等学校 歴史総合 || AB判
|-
| 711 || 第一学習社 || 高等学校 新歴史総合 過去との対話、つなぐ未来 || AB判
|-
| 712 || 明成社 || 私たちの歴史総合 || B5判
|}
===日本史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 日本史探究 || B5判
|-
| 702 || 実教出版 || 日本史探究 || B5判変型
|-
| 703 || 実教出版 ||精選日本史探究 今につなぐ 未来をえがく || AB判
|-
| 704 || 清水書院 || 高等学校 日本史探究 || B5判
|-
| 705 || 山川出版社 || 詳説日本史 || B5判変型
|-
| 706 || 山川出版社 || 高校日本史|| B5判
|-
| 707 || 第一学習社 || 高等学校 日本史探究 || B5判
|}
===世界史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 世界史探究 || B5判
|-
| 702 || 実教出版 || 世界史探究 || B5判変型
|-
| 703 || 帝国書院 || 新詳世界史探究 || B5判
|-
| 704 || 山川出版社 || 詳説世界史 || B5判変型
|-
| 705 || 山川出版社 || 高校世界史 || B5判
|-
| 706 || 山川出版社 || 新世界史 || B5判変型
|-
| 707 || 第一学習社 || 高等学校 世界史探究 || B5判
|}
===地図===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新高等地図 || A4判
|-
| 702 || 帝国書院 || 新詳高等地図 || AB判
|-
| 703 || 帝国書院 || 標準高等地図 || A4判
|-
| 704 || 二宮書店 || 高等地図帳 || B5判
|-
| 705 || 二宮書店 || 詳解現代地図 最新版 || AB判
|-
| 706 || 二宮書店 || 基本地図帳 || A4判
|-
| 707 || 二宮書店 || コンパクト地理総合地図 || AB判変型
|}
==公民==
===公共===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||公共||AB判
|-
|702||教育図書||公共||B5判
|-
|703||実教出版||詳述公共||A5判
|-
|704||実教出版||公共||B5判
|-
|705||清水書院||高等学校 公共||B5判
|-
|706||清水書院||私たちの公共||AB判
|-
|707||帝国書院||高等学校 公共||AB判
|-
|708||数研出版||公共(令和4年度)||
|-
|709||数研出版||高等学校 公共 これからの社会について考える||AB判
|-
|710||第一学習社||高等学校 公共||B5判
|-
|711||第一学習社||高等学校 新公共||AB判
|-
|712||東京法令出版||公共||B5判
|-
|713||数研出版||新版 公共(令和5年度)||B5判
|}
===倫理===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 倫理 || B5判変型
|-
| 702 || 実教出版 || 詳述倫理 || A5判
|-
| 703 || 清水書院 || 高等学校 新倫理 || A5判
|-
| 704 || 数研出版 || 倫理 || A5判
|-
| 705 || 第一学習社 || 高等学校 倫理 || B5判
|}
===政治・経済===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
|701||東京書籍||政治・経済||B5判変型
|-
|702||実教出版||詳述政治・経済||A5判
|-
|703||実教出版||最新政治・経済||B5判
|-
|704||清水書院||高等学校 政治・経済||A5判
|-
|705||数研出版||政治・経済||A5判
|-
|706||第一学習社||高等学校 政治・経済||B5判
|}
==数学==
===数学Ⅰ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅰ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅰ Standard || A5判
|-
| 703 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学Ⅰ || B5判
|-
| 705 || 東京書籍 || 新数学Ⅰ 解答編 || B5判
|-
| 706 || 実教出版 || 数学Ⅰ Progress || A5判
|-
| 707 || 実教出版 || 新編数学Ⅰ || A5判
|-
| 708|| 実教出版 || 高校数学Ⅰ || B5判
|-
| 709 || 啓林館 || 数学Ⅰ || A5判
|-
| 710 || 啓林館 || 新編数学Ⅰ || A5判
|-
| 711 || 啓林館 || 深進数学Ⅰ || A5判
|-
| 712 || 数研出版 || 数学Ⅰ || A5判
|-
| 713 || 数研出版 || 高等学校 数学Ⅰ || A5判
|-
| 714 || 数研出版 || 新編 数学Ⅰ || A5判
|-
| 715 || 数研出版 || 最新 数学Ⅰ || A5判
|-
| 716 || 数研出版 || 新 高校の数学Ⅰ || B5判
|-
| 717 ||数研出版 || NEXT 数学Ⅰ || A5判
|-
| 718 || 第一学習社|| 新編数学Ⅰ || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Ⅰサポートブック || B5判変型版
|}
===数学Ⅱ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅱ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅱ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅱ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅱ || A5判
|-
| 705|| 実教出版 || 高校数学Ⅱ || B5判
|-
| 706 || 啓林館 || 数学Ⅱ || A5判
|-
| 707 || 啓林館 || 新編数学Ⅱ || A5判
|-
| 708 || 啓林館 || 深進数学Ⅱ || A5判
|-
| 709 || 数研出版 || 数学Ⅱ || A5判
|-
| 710 || 数研出版 || 高等学校 数学Ⅱ || A5判
|-
| 711 || 数研出版 || 新編 数学Ⅱ || A5判
|-
| 712 || 数研出版 || 最新 数学Ⅱ || A5判
|-
| 713 ||数研出版 || NEXT 数学Ⅱ || A5判
|-
| 714 || 第一学習社|| 新編数学Ⅱ || B5判変型版
|-
| 715 || 第一学習社 || 新編数学Ⅱサポートブック || B5判変型版
|-
| 716 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 717 || 東京書籍 || 新数学Ⅱ || B5判
|-
| 718 || 東京書籍 || 新数学Ⅱ 解答編 || B5判
|-
| 719 || 数研出版 || 新 高校の数学Ⅱ || B5判
|}
===数学Ⅲ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅲ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅲ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅲ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅲ || A5判
|-
| 705 || 啓林館 || 数学Ⅲ || A5判
|-
| 706 || 啓林館 || 新編数学Ⅲ || A5判
|-
| 707 || 啓林館 || 深進数学Ⅲ || A5判
|-
| 708 || 数研出版 || 数学Ⅲ || A5判
|-
| 709 || 数研出版 || 高等学校 数学Ⅲ || A5判
|-
| 710 || 数研出版 || 新編 数学Ⅲ || A5判
|-
| 711 || 数研出版 || 最新 数学Ⅲ || A5判
|-
| 712 ||数研出版 || NEXT 数学Ⅲ || A5判
|}
===数学A===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学A Advanced || A5判
|-
| 702 || 東京書籍 || 数学A Standard || A5判
|-
| 703 || 東京書籍 || 数学A Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学A || B5判
|-
| 705 || 東京書籍 || 新数学A 解答編 || B5判
|-
| 706 || 実教出版 || 数学A Progress || A5判
|-
| 707 || 実教出版 || 新編数学A || A5判
|-
| 708|| 実教出版 || 高校数学A || B5判
|-
| 709 || 啓林館 || 数学A || A5判
|-
| 710 || 啓林館 || 新編数学A || A5判
|-
| 711 || 啓林館 || 深進数学A || A5判
|-
| 712 || 数研出版 || 数学A || A5判
|-
| 713 || 数研出版 || 高等学校 数学A || A5判
|-
| 714 || 数研出版 || 新編 数学A || A5判
|-
| 715 || 数研出版 || 最新 数学A || A5判
|-
| 716 || 数研出版 || 新 高校の数学A || B5判
|-
| 717 ||数研出版 || NEXT 数学A || A5判
|-
| 718 || 第一学習社|| 新編数学A || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Aサポートブック || B5判変型版
|}
===数学B===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学B Advanced || A5判
|-
| 702 || 東京書籍 || 数学B Standard || A5判
|-
| 703 || 東京書籍 || 数学B Essence || B5判変型版
|-
| 704 || 実教出版 || 数学B Progress || A5判
|-
| 705 || 実教出版 || 新編数学B || A5判
|-
| 706|| 実教出版 || 高校数学B || B5判
|-
| 707 || 啓林館 || 数学B || A5判
|-
| 708 || 啓林館 || 新編数学B || A5判
|-
| 709 || 啓林館 || 深進数学B || A5判
|-
| 710 || 数研出版 || 数学B || A5判
|-
| 711 || 数研出版 || 高等学校 数学B || A5判
|-
| 712 || 数研出版 || 新編 数学B || A5判
|-
| 713 || 数研出版 || 最新 数学B || A5判
|-
| 714 || 数研出版 || 新 高校の数学B || B5判
|-
| 715 ||数研出版 || NEXT 数学B || A5判
|-
| 716 || 第一学習社|| 新編数学B || B5判変型版
|}
===数学C===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学C Advanced || A5判
|-
| 702 || 東京書籍 || 数学C Standard || A5判
|-
| 703 || 実教出版 || 数学C Progress || A5判
|-
| 704 || 実教出版 || 新編数学C || A5判
|-
| 705 || 啓林館 || 数学C || A5判
|-
| 706 || 啓林館 || 新編数学C || A5判
|-
| 707 || 啓林館 || 深進数学C || A5判
|-
| 708 || 数研出版 || 数学C || A5判
|-
| 709 || 数研出版 || 高等学校 数学C || A5判
|-
| 710 || 数研出版 || 新編 数学C || A5判
|-
| 711 || 数研出版 || 最新 数学C || A5判
|-
| 712 || 数研出版 || NEXT 数学C || A5判
|-
| 713 || 第一学習社 || 新編数学C || B5判変型
|}
==理科==
===科学と人間生活===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 科学と人間生活 || B5判変型
|-
| 702 || 実教出版 || 科学と人間生活 || B5判
|-
| 703 || 啓林館 || 高等学校 科学と人間生活 || B5判
|-
| 704 || 数研出版 || 科学と人間生活 || AB判
|-
| 705 || 第一学習社 || 高等学校 科学と人間生活 || B5判
|}
===物理基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|物理基礎
|B5判変型
|-
|702
|東京書籍
|新編物理基礎
|B5判
|-
|703
|実教出版
|物理基礎
|B5判
|-
|704
|実教出版
|高校物理基礎
|B5判
|-
|705
|啓林館
|高等学校 物理基礎
|A5判
|-
|706
|啓林館
|高等学校 考える物理基礎
|B5判
|-
|707
|数研出版
|物理基礎
|A5判
|-
|708
|数研出版
|新編 物理基礎
|B5判
|-
|709
|第一学習社
|高等学校 物理基礎
|B5判変型
|-
|710
|第一学習社
|高等学校 新物理基礎
|B5判
|}
===物理===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|物理
|B5判変型
|-
|702
|実教出版
|物理
|B5判
|-
|703
|啓林館
|高等学校 物理
|A5判
|-
|704
|啓林館
|高等学校 総合物理1 様々な運動 熱 波
|A5判
|-
|705
|啓林館
|高等学校 総合物理2 電気と磁気 原子・分子の世界
|A5判
|-
|706
|数研出版
|物理
|A5判
|-
|707
|数研出版
|総合物理1 力と運動・熱
|A5判
|-
|708
|数研出版
|総合物理2 波・電気と磁気・原子
|A5判
|-
|709
|第一学習社
|高等学校 物理
|B5判変型
|}
===化学基礎===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学基礎
|B5判変型
|-
|702
|東京書籍
|新編化学基礎
|B5判
|-
|703
|実教出版
|化学基礎 academia
|A5判
|-
|704
|実教出版
|化学基礎
|B5判
|-
|705
|実教出版
|高校化学基礎
|B5判
|-
|706
|啓林館
|高等学校 化学基礎
|A5判
|-
|707
|啓林館
|i版 化学基礎
|AB判
|-
|708
|数研出版
|化学基礎
|A5判
|-
|709
|数研出版
|高等学校 化学基礎
|B5判変型
|-
|710
|数研出版
|新編 化学基礎
|B5判
|-
|711
|第一学習社
|高等学校 化学基礎
|B5判変型
|-
|712
|第一学習社
|高等学校 化学基礎
|B5判
|}
===化学===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学 Vol.1 理論編
|B5判変型
|-
|702
|東京書籍
|化学 Vol.2 物質編
|B5判変型
|-
|703
|実教出版
|化学 academia
|A5判
|-
|704
|実教出版
|化学
|B5判
|-
|705
|啓林館
|高等学校 化学
|A5判
|-
|706
|数研出版
|化学
|A5判
|-
|707
|数研出版
|新編 化学
|B5判
|-
|708
|第一学習社
|高等学校 化学
|B5判変型
|}
===生物基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|生物基礎
|B5判変型
|-
|702
|東京書籍
|新編生物基礎
|B5判
|-
|703
|実教出版
|生物基礎
|B5判
|-
|704
|実教出版
|高校生物基礎
|B5判
|-
|705
|啓林館
|高等学校 生物基礎
|B5判変型
|-
|706
|啓林館
|i版 生物基礎
|AB判
|-
|707
|数研出版
|生物基礎
|A5判
|-
|708
|数研出版
|高等学校 生物基礎
|B5判変型
|-
|709
|数研出版
|新編 生物基礎
|B5判
|-
|710
|第一学習社
|高等学校 生物基礎
|B5判変型
|-
|711
|第一学習社
|高等学校 新生物基礎
|B5判
|}
===生物===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||生物||B5判変型
|-
|702||実教出版||生物||B5判
|-
|703||啓林館||高等学校 生物||B5判変型
|-
|704||数研出版||生物||B5判変型
|-
|705||第一学習社||高等学校 生物||B5判変型
|}
===地学基礎===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||地学基礎||B5判
|-
|702||実教出版||地学基礎||B5判
|-
|703||啓林館||高等学校 地学基礎||B5判変型
|-
|704||数研出版||高等学校 地学基礎||B5判変型
|-
|705||第一学習社||高等学校 地学基礎||B5判
|}
===地学===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||啓林館||高等学校 地学||A5判
|}
== 保健体育 ==
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||大修館書店||現代高等保健育||B5判
|-
|702||大修館書店||新高等保健体育||B5判変型
|-
|703||第一学習社||高等学校 保健体育 Textbook||B5判
|-
|704||第一学習社||高等学校 保健体育 Activity||B5判
|}
== 芸術 ==
=== 音楽Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅰ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽1 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA1 || A4判
|-
| 704 || 音楽之友社 || ON! 1 || A4判変型
|}
=== 音楽Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅱ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽2 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA2 || A4判
|-
| 704 || 音楽之友社 || ON! 2 || A4判変型
|}
=== 美術Ⅰ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 ||美術1 || A4判変型
|-
| 702 ||日本文教出版 ||高校生の美術1 ||A4判
|-
| 703 || 日本文教出版 ||高校美術 ||A4判変型
|}
=== 美術Ⅱ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 || 美術2 ||A4判変型
|-
| 702 || 日本文教出版 || 高校生の美術2 ||A4判
|}
=== 工芸Ⅰ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅰ||A4判
|}
=== 工芸Ⅱ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅱ||A4判
|}
=== 書道Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅰ || A4判
|-
| 702 || 教育図書 || 書Ⅰ || A4判
|-
| 703 || 教育図書 || 書Ⅰプライマリーブック || A4判
|-
| 704 || 教育出版 || 書道Ⅰ || A4判
|-
| 705 || 光村図書出版 || 書Ⅰ || A4判
|}
=== 書道Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅱ || A4判
|-
| 702 || 教育図書 || 書Ⅱ || A4判
|-
| 703 || 教育出版 || 書道Ⅱ || A4判
|-
| 704 || 光村図書出版 || 書Ⅱ || A4判
|}
== 外国語 ==
=== 英語コミュニケーションⅠ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅰ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅠ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅠ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅠ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅠ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅠ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅠ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅠ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅠ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅰ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅰ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅰ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅰ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅰ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅰ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅰ
|AB判
|-
|719
|文英堂
|Grove English CommunicationⅠ
|B5判
|-
|720
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅰ
|B5判
|-
|721
|第一学習社
|CREATIVE English Communication Ⅰ
|B5判
|-
|722
|第一学習社
|Vivid English Communication Ⅰ
|B5判
|-
|723
|桐原書店
|Heartening English Communication Ⅰ
|B5判
|-
|724
|いいずな書店
|New Rays English Communication Ⅰ
|B5判変型
|-
|725
|Cambridge University Press & Assessment
|Cambridge Experience 1
|A4判
|}
=== 英語コミュニケーションⅡ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅱ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅡ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅡ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅡ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅡ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅡ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅡ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅡ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅡ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅱ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅱ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅱ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅱ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅱ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅱ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅱ
|AB判
|-
|718
|文英堂
|Grove English CommunicationⅡ
|B5判
|-
|719
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅱ
|B5判
|-
|720
|第一学習社
|CREATIVE English Communication Ⅱ
|B5判
|-
|721
|第一学習社
|Vivid English Communication Ⅱ
|B5判
|-
|722
|桐原書店
|Heartening English Communication Ⅱ
|B5判
|-
|723
|いいずな書店
|New Rays English Communication Ⅱ
|B5判変型
|-
|724
|Cambridge University Press & Assessment
|Cambridge Experience 2
|A4判
|}
=== 論理・表現Ⅰ ===
=== 論理・表現Ⅱ ===
== 家庭 ==
=== 家庭基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭基礎 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭基礎365 || AB判
|-
| 703 || 教育図書 || 家庭基礎 つながる暮らし 共に創る未来 || B5判
|-
| 704 || 教育図書 || Survive!! 高等学校 家庭基礎 || AB判
|-
| 705 || 実教出版 || 家庭基礎 気づく力 築く未来 || AB判
|-
| 706 || 実教出版 || Agenda家庭基礎 || B5判
|-
| 707 || 実教出版 || 図説家庭基礎 || AB判
|-
| 708 || 開隆堂 || 家庭基礎 明日の生活を築く || AB判
|-
| 709 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭基礎』で生活をつくろう || A4判
|-
| 710 || 第一学習社 || 高等学校 家庭基礎 持続可能な未来をつくる || AB判
|}
=== 家庭総合 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭総合 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭総合365 || AB判
|-
| 703 || 実教出版 || 家庭総合 || AB判
|-
| 704 || 開隆堂 || 家庭総合 明日の生活を築く || AB判
|-
| 705 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭総合』で生活をつくろう || A4判
|-
| 706 || 第一学習社 || 高等学校 家庭総合 持続可能な未来をつくる || AB判
|}
== 情報 ==
=== 情報Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新編情報Ⅰ || B5判
|-
| 702 || 東京書籍 || 情報Ⅰ Step Forward! || B5判
|-
| 703 || 実教出版 || 高校情報Ⅰ Python || B5判
|-
| 704 || 実教出版 || 高校情報Ⅰ JavaScript || B5判
|-
| 705 || 実教出版 || 最新情報Ⅰ || B5判
|-
| 706 || 実教出版 || 図説情報Ⅰ || AB判
|-
| 707 || 開隆堂 || 実践 情報Ⅰ || B5判
|-
| 708 || 数研出版 || 高等学校 情報Ⅰ || B5判
|-
| 709 || 数研出版 || 情報Ⅰ Next || B5判
|-
| 710 || 日本文教出版 || 情報Ⅰ || B5判変型
|-
| 711 || 日本文教出版 || 情報Ⅰ図解と実習-図解編 || B5判変型
|-
| 712 || 日本文教出版 || 情報Ⅰ図解と実習-実習編 || B5判変型
|-
| 713 || 第一学習社 || 高等学校 情報Ⅰ || AB判
|}
=== 情報Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 情報Ⅱ || B5判
|-
| 702 || 実教出版 || 情報Ⅱ || B5判
|-
| 703 || 日本文教出版 || 情報Ⅱ || B5判変型
|}
== 理数 ==
=== 理数探究基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 啓林館 || 理数探究基礎 未来に向かって || A4判
|-
| 702 || 数研出版 || 理数探究基礎 || B5判
|}
== 農業 ==
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|実教出版
|農業と環境
|B5判
|-
|702
|実教出版
|農業と情報
|B5判
|-
|708
|実教出版
|草花
|B5判
|-
|710
|実教出版
|栽培と環境
|B5判
|-
|709
|実教出版
|農業機械
|B5判
|-
|703
|実教出版
|植物バイオテクノロジー
|B5判
|-
|704
|実教出版
|食品製造
|B5判
|-
|711
|実教出版
|生物活用
|B5判
|-
|705
|実教出版
|森林科学
|B5判
|-
|712
|実教出版
|森林経営
|
|-
|706
|実教出版
|農業土木設計
|B5判
|-
|713
|東京電機大学
|農業土木施工
|B5判
|-
|707
|実教出版
|造園計画
|B5判
|-
|714
|東京電機大学
|造園施工管理
|B5判
|}
== 工業 ==
== 商業 ==
== 水産 ==
== 家庭 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || ファッションデザイン || B5判
|-
| 702 || 教育図書 || フードデザイン Food Changes LIFE || AB判
|-
| 703 || 実教出版 || フードデザイン || AB判
|-
| 704 || 実教出版 || 生活産業情報 || B5判
|-
| 705 || 実教出版 || ファッション造形基礎 || B5判
|-
| 706 || 教育図書 || 保育基礎 ようこそ、ともに育ち合う保育の世界へ || AB判
|-
| 707 || 実教出版 || 保育基礎 || B5判
|-
| 708 || 実教出版 || 消費生活 || B5判
|-
| 709 || 実教出版 || 保育実践 || B5判
|-
| 710 || 実教出版 || 服飾文化 || B5判
|}
== 看護 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 基礎看護 || B5判
|}
== 情報 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 情報産業と社会 || B5判
|-
| 702 || 実教出版 || 情報の表現と管理 || B5判
|-
| 703 || 東京電機大学 || 情報システムのプログラミング || B5判
|-
| 704 || 実教出版 || 情報セキュリティ || B5判
|-
| 705 || 実教出版 || 情報デザイン || B5判
|-
| 706 || 実教出版 || ネットワークシステム || B5判
|-
| 707 || 実教出版 || データベース || B5判
|}
== 福祉 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 社会福祉基礎 || B5判
|-
| 702 || 実教出版 || 介護福祉基礎 || B5判
|-
| 703 || 実教出版 || 生活支援技術 || B5判
|-
| 704 || 実教出版 || こころとからだの理解 || B5判
|}
==脚注==
*[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
4t80m5a5hovpx8ppznjdvbbdptja9h9
205815
205814
2022-07-25T05:38:28Z
Kwawe
68789
/* 英語コミュニケーションⅠ */
wikitext
text/x-wiki
{{Pathnav|メインページ|[[小学校・中学校・高等学校の学習]]>[[高等学校の学習]]>[[検定教科書]]|frame=1}}
このページでは、'''高等学校の教科書番号'''について説明します。教科書番号については、[[../|この上層ページ]]をご覧ください。
本内容は令和5年度以降の教科書目録をまとめています。
※以下、このページは新高校1年生から使う教科書を掲載しています。旧課程(現高校2~3年生)の教科書はこのページに掲載しておりません。
==国語==
※国語は本を読ますための性格なのか、A5版がほとんどです。
===現代の国語===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編現代の国語||A5判
|-
|702||東京書籍||精選現代の国語||A5判
|-
|703||東京書籍||現代の国語||A5判
|-
|704||三省堂||精選 現代の国語||A5判
|-
|705||三省堂||新 現代の国語||A5判
|-
|706||大修館書店||現代の国語||A5判
|-
|707||大修館書店||新編 現代の国語||B5判
|-
|708||数研出版||現代の国語||A5判
|-
|709||数研出版||高等学校 現代の国語||A5判
|-
|710||数研出版||新編 現代の国語||A5判
|-
|711||明治書院||精選 現代の国語||A5判
|-
|712||筑摩書房||現代の国語||A5判
|-
|713||第一学習社||高等学校 現代の国語||A5判
|-
|714||第一学習社||高等学校 精選現代の国語||A5判
|-
|715||第一学習社||高等学校 標準現代の国語||A5判
|-
|716||第一学習社||高等学校 新編現代の国語||B5判
|-
|717||桐原書店||探求 現代の国語||A5判
|-
|}
===言語文化===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編言語文化||A5判
|-
|702||東京書籍||精選言語文化||A5判
|-
|703||三省堂||精選 言語文化||A5判
|-
|704||三省堂||新 言語文化||A5判
|-
|705||大修館書店||言語文化||A5判
|-
|706||大修館書店||新編 言語文化||B5判
|-
|708||数研出版||高等学校 言語文化||A5判
|-
|709||数研出版||新編 言語文化||A5判
|-
|710||文英堂||言語文化||A5判
|-
|711||明治書院||精選言語文化||A5判
|-
|712||筑摩書房||言語文化||A5判
|-
|713||第一学習社||高等学校 言語文化||A5判
|-
|714||第一学習社||高等学校 精選言語文化||A5判
|-
|715||第一学習社||高等学校 標準言語文化||A5判
|-
|716||第一学習社||高等学校 新編言語文化||B5判
|-
|717||桐原書店||探求 言語文化||A5判
|}
===論理国語 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 論理国語 || A5判
|-
| 702 || 東京書籍 || 精選論理国語 || A5判
|-
| 703 || 三省堂 || 精選 論理国語 || A5判
|-
| 704 || 三省堂 || 新 論理国語 || A5判
|-
| 705 || 大修館書店 || |論理国語 || A5判
|-
| 706 || 大修館書店 || 新編 論理国語 || A5判
|-
| 707 || 数研出版 || 精選 論理国語 || A5判
|-
| 708 || 数研出版 || 論理国語 || A5判
|-
| 709 || 明治書院 || 精選 論理国語 || A5判
|-
| 710 || 筑摩書房 || 論理国語 || A5判
|-
| 711 || 第一学習社 || 高等学校 論理国語 || A5判
|-
| 712|| 第一学習社 || 高等学校 標準論理国語 || A5判
|-
| 713 || 桐原書店 || 探求 論理国語 || A5判
|}
===文学国語===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 文学国語 || A5判
|-
| 702 || 三省堂 || 精選 文学国語 || A5判
|-
| 703 || 三省堂 || 新 文学国語 || A5判
|-
| 704 || 大修館書店 || |文学国語 || A5判
|-
| 705 || 大修館書店 || 新編 文学国語 || A5判
|-
| 706 || 数研出版 || 文学国語 || A5判
|-
| 707 || 明治書院 || 精選 文学国語 || A5判
|-
| 708 || 筑摩書房 || 文学国語 || A5判
|-
| 709 || 第一学習社 || 高等学校 文学国語 || A5判
|-
| 710 || 第一学習社 || 高等学校 標準文学国語 || A5判
|-
| 711 || 桐原書店 || 探求 文学国語 || A5判
|}
===国語表現===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 大修館書店 || 国語表現 || B5判
|}
===古典探究 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社!! 教科書名!! 判型
|-
| 701 || 東京書籍 ||新編古典探究 || A5判
|-
| 702 || 東京書籍 ||精選古典探究 古文編 || A5判
|-
| 703 || 東京書籍 ||精選古典探究 漢文編 || A5判
|-
| 704 || 三省堂 ||精選 古典探究 古文編 || A5判
|-
| 705 || 三省堂 ||精選 古典探究 漢文編 || A5判
|-
| 706 || 大修館書店 ||古典探究 古文編 || A5判
|-
| 707 || 大修館書店 ||古典探究 漢文編 || A5判
|-
| 708 || 大修館書店 ||精選 古典探究 || A5判
|-
| 709 || 数研出版 ||古典探究 古文編 || A5判
|-
| 710 || 数研出版 ||古典探究 漢文編 || A5判
|-
| 711 || 数研出版 ||高等学校 古典探究 || A5判
|-
| 712 || 文英堂 ||古典探究 || A5判
|-
| 713 || 明治書院 ||精選 古典探究 古文編|| A5判
|-
| 714 || 明治書院 ||精選 古典探究 漢文編 || A5判
|-
| 715 || 筑摩書房 ||古典探究 古文編 || A5判
|-
| 716 || 筑摩書房 ||古典探究 漢文編 || A5判
|-
| 717 || 第一学習社 ||高等学校 古典探究 古文編 || A5判
|-
| 718 || 第一学習社 || 高等学校 古典探究 漢文編 || A5判
|-
| 719 || 第一学習社 || 高等学校 精選古典探究 || A5判
|-
| 720 || 第一学習社 || 高等学校 標準古典探究 || A5判
|-
| 721 || 桐原書店 || 探求 古典探究 古文編 || A5判
|-
| 722 || 桐原書店 || 探求 古典探究 漢文編 || A5判
|}
==地理歴史==
===地理総合===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 地理総合 || AB判
|-
| 702 || 実教出版 || 地理総合 || AB判
|-
| 703 || 帝国書院 || 高等学校 地理総合 || AB判
|-
| 704 || 二宮書店 || 地理総合 世界に学び地域へつなぐ || B5判
|-
| 705 || 二宮書店 || わたしたちの地理総合 世界から日本へ || AB判
|-
| 706 || 第一学習社 || 高等学校 地理総合 世界を学び、地域をつくる || AB判
|-
| 707 || 帝国書院 || 高校生の地理総合 || AB判
|}
===地理探究===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
| 701 ||東京書籍||地理探究||AB判
|-
|702||帝国書院||新詳地理探究||B5判
|-
|703||二宮書店|| 地理探究||B5判
|}
===歴史総合===
{| class="wikitable sortable"
|-
! 番号!! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新選歴史総合 || AB判
|-
| 702 || 東京書籍 || 詳解歴史総合 || B5判
|-
| 703 || 実教出版 || 詳述歴史総合 || B5判
|-
| 704 || 実教出版 || 歴史総合 || AB判
|-
| 705 || 清水書院 || 私たちの歴史総合 || A4判
|-
| 706 || 帝国書院 || 明解 歴史総合 || AB判
|-
| 707 || 山川出版社 || 歴史総合 近代から現代へ || B5判
|-
| 708 || 山川出版社 || 現代の歴史総合 みる・読みとく・考える || AB判
|-
| 709 || 山川出版社 || わたしたちの歴史 日本から世界へ || AB判
|-
| 710 || 第一学習社 || 高等学校 歴史総合 || AB判
|-
| 711 || 第一学習社 || 高等学校 新歴史総合 過去との対話、つなぐ未来 || AB判
|-
| 712 || 明成社 || 私たちの歴史総合 || B5判
|}
===日本史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 日本史探究 || B5判
|-
| 702 || 実教出版 || 日本史探究 || B5判変型
|-
| 703 || 実教出版 ||精選日本史探究 今につなぐ 未来をえがく || AB判
|-
| 704 || 清水書院 || 高等学校 日本史探究 || B5判
|-
| 705 || 山川出版社 || 詳説日本史 || B5判変型
|-
| 706 || 山川出版社 || 高校日本史|| B5判
|-
| 707 || 第一学習社 || 高等学校 日本史探究 || B5判
|}
===世界史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 世界史探究 || B5判
|-
| 702 || 実教出版 || 世界史探究 || B5判変型
|-
| 703 || 帝国書院 || 新詳世界史探究 || B5判
|-
| 704 || 山川出版社 || 詳説世界史 || B5判変型
|-
| 705 || 山川出版社 || 高校世界史 || B5判
|-
| 706 || 山川出版社 || 新世界史 || B5判変型
|-
| 707 || 第一学習社 || 高等学校 世界史探究 || B5判
|}
===地図===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新高等地図 || A4判
|-
| 702 || 帝国書院 || 新詳高等地図 || AB判
|-
| 703 || 帝国書院 || 標準高等地図 || A4判
|-
| 704 || 二宮書店 || 高等地図帳 || B5判
|-
| 705 || 二宮書店 || 詳解現代地図 最新版 || AB判
|-
| 706 || 二宮書店 || 基本地図帳 || A4判
|-
| 707 || 二宮書店 || コンパクト地理総合地図 || AB判変型
|}
==公民==
===公共===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||公共||AB判
|-
|702||教育図書||公共||B5判
|-
|703||実教出版||詳述公共||A5判
|-
|704||実教出版||公共||B5判
|-
|705||清水書院||高等学校 公共||B5判
|-
|706||清水書院||私たちの公共||AB判
|-
|707||帝国書院||高等学校 公共||AB判
|-
|708||数研出版||公共(令和4年度)||
|-
|709||数研出版||高等学校 公共 これからの社会について考える||AB判
|-
|710||第一学習社||高等学校 公共||B5判
|-
|711||第一学習社||高等学校 新公共||AB判
|-
|712||東京法令出版||公共||B5判
|-
|713||数研出版||新版 公共(令和5年度)||B5判
|}
===倫理===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 倫理 || B5判変型
|-
| 702 || 実教出版 || 詳述倫理 || A5判
|-
| 703 || 清水書院 || 高等学校 新倫理 || A5判
|-
| 704 || 数研出版 || 倫理 || A5判
|-
| 705 || 第一学習社 || 高等学校 倫理 || B5判
|}
===政治・経済===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
|701||東京書籍||政治・経済||B5判変型
|-
|702||実教出版||詳述政治・経済||A5判
|-
|703||実教出版||最新政治・経済||B5判
|-
|704||清水書院||高等学校 政治・経済||A5判
|-
|705||数研出版||政治・経済||A5判
|-
|706||第一学習社||高等学校 政治・経済||B5判
|}
==数学==
===数学Ⅰ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅰ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅰ Standard || A5判
|-
| 703 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学Ⅰ || B5判
|-
| 705 || 東京書籍 || 新数学Ⅰ 解答編 || B5判
|-
| 706 || 実教出版 || 数学Ⅰ Progress || A5判
|-
| 707 || 実教出版 || 新編数学Ⅰ || A5判
|-
| 708|| 実教出版 || 高校数学Ⅰ || B5判
|-
| 709 || 啓林館 || 数学Ⅰ || A5判
|-
| 710 || 啓林館 || 新編数学Ⅰ || A5判
|-
| 711 || 啓林館 || 深進数学Ⅰ || A5判
|-
| 712 || 数研出版 || 数学Ⅰ || A5判
|-
| 713 || 数研出版 || 高等学校 数学Ⅰ || A5判
|-
| 714 || 数研出版 || 新編 数学Ⅰ || A5判
|-
| 715 || 数研出版 || 最新 数学Ⅰ || A5判
|-
| 716 || 数研出版 || 新 高校の数学Ⅰ || B5判
|-
| 717 ||数研出版 || NEXT 数学Ⅰ || A5判
|-
| 718 || 第一学習社|| 新編数学Ⅰ || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Ⅰサポートブック || B5判変型版
|}
===数学Ⅱ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅱ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅱ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅱ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅱ || A5判
|-
| 705|| 実教出版 || 高校数学Ⅱ || B5判
|-
| 706 || 啓林館 || 数学Ⅱ || A5判
|-
| 707 || 啓林館 || 新編数学Ⅱ || A5判
|-
| 708 || 啓林館 || 深進数学Ⅱ || A5判
|-
| 709 || 数研出版 || 数学Ⅱ || A5判
|-
| 710 || 数研出版 || 高等学校 数学Ⅱ || A5判
|-
| 711 || 数研出版 || 新編 数学Ⅱ || A5判
|-
| 712 || 数研出版 || 最新 数学Ⅱ || A5判
|-
| 713 ||数研出版 || NEXT 数学Ⅱ || A5判
|-
| 714 || 第一学習社|| 新編数学Ⅱ || B5判変型版
|-
| 715 || 第一学習社 || 新編数学Ⅱサポートブック || B5判変型版
|-
| 716 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 717 || 東京書籍 || 新数学Ⅱ || B5判
|-
| 718 || 東京書籍 || 新数学Ⅱ 解答編 || B5判
|-
| 719 || 数研出版 || 新 高校の数学Ⅱ || B5判
|}
===数学Ⅲ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅲ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅲ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅲ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅲ || A5判
|-
| 705 || 啓林館 || 数学Ⅲ || A5判
|-
| 706 || 啓林館 || 新編数学Ⅲ || A5判
|-
| 707 || 啓林館 || 深進数学Ⅲ || A5判
|-
| 708 || 数研出版 || 数学Ⅲ || A5判
|-
| 709 || 数研出版 || 高等学校 数学Ⅲ || A5判
|-
| 710 || 数研出版 || 新編 数学Ⅲ || A5判
|-
| 711 || 数研出版 || 最新 数学Ⅲ || A5判
|-
| 712 ||数研出版 || NEXT 数学Ⅲ || A5判
|}
===数学A===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学A Advanced || A5判
|-
| 702 || 東京書籍 || 数学A Standard || A5判
|-
| 703 || 東京書籍 || 数学A Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学A || B5判
|-
| 705 || 東京書籍 || 新数学A 解答編 || B5判
|-
| 706 || 実教出版 || 数学A Progress || A5判
|-
| 707 || 実教出版 || 新編数学A || A5判
|-
| 708|| 実教出版 || 高校数学A || B5判
|-
| 709 || 啓林館 || 数学A || A5判
|-
| 710 || 啓林館 || 新編数学A || A5判
|-
| 711 || 啓林館 || 深進数学A || A5判
|-
| 712 || 数研出版 || 数学A || A5判
|-
| 713 || 数研出版 || 高等学校 数学A || A5判
|-
| 714 || 数研出版 || 新編 数学A || A5判
|-
| 715 || 数研出版 || 最新 数学A || A5判
|-
| 716 || 数研出版 || 新 高校の数学A || B5判
|-
| 717 ||数研出版 || NEXT 数学A || A5判
|-
| 718 || 第一学習社|| 新編数学A || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Aサポートブック || B5判変型版
|}
===数学B===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学B Advanced || A5判
|-
| 702 || 東京書籍 || 数学B Standard || A5判
|-
| 703 || 東京書籍 || 数学B Essence || B5判変型版
|-
| 704 || 実教出版 || 数学B Progress || A5判
|-
| 705 || 実教出版 || 新編数学B || A5判
|-
| 706|| 実教出版 || 高校数学B || B5判
|-
| 707 || 啓林館 || 数学B || A5判
|-
| 708 || 啓林館 || 新編数学B || A5判
|-
| 709 || 啓林館 || 深進数学B || A5判
|-
| 710 || 数研出版 || 数学B || A5判
|-
| 711 || 数研出版 || 高等学校 数学B || A5判
|-
| 712 || 数研出版 || 新編 数学B || A5判
|-
| 713 || 数研出版 || 最新 数学B || A5判
|-
| 714 || 数研出版 || 新 高校の数学B || B5判
|-
| 715 ||数研出版 || NEXT 数学B || A5判
|-
| 716 || 第一学習社|| 新編数学B || B5判変型版
|}
===数学C===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学C Advanced || A5判
|-
| 702 || 東京書籍 || 数学C Standard || A5判
|-
| 703 || 実教出版 || 数学C Progress || A5判
|-
| 704 || 実教出版 || 新編数学C || A5判
|-
| 705 || 啓林館 || 数学C || A5判
|-
| 706 || 啓林館 || 新編数学C || A5判
|-
| 707 || 啓林館 || 深進数学C || A5判
|-
| 708 || 数研出版 || 数学C || A5判
|-
| 709 || 数研出版 || 高等学校 数学C || A5判
|-
| 710 || 数研出版 || 新編 数学C || A5判
|-
| 711 || 数研出版 || 最新 数学C || A5判
|-
| 712 || 数研出版 || NEXT 数学C || A5判
|-
| 713 || 第一学習社 || 新編数学C || B5判変型
|}
==理科==
===科学と人間生活===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 科学と人間生活 || B5判変型
|-
| 702 || 実教出版 || 科学と人間生活 || B5判
|-
| 703 || 啓林館 || 高等学校 科学と人間生活 || B5判
|-
| 704 || 数研出版 || 科学と人間生活 || AB判
|-
| 705 || 第一学習社 || 高等学校 科学と人間生活 || B5判
|}
===物理基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|物理基礎
|B5判変型
|-
|702
|東京書籍
|新編物理基礎
|B5判
|-
|703
|実教出版
|物理基礎
|B5判
|-
|704
|実教出版
|高校物理基礎
|B5判
|-
|705
|啓林館
|高等学校 物理基礎
|A5判
|-
|706
|啓林館
|高等学校 考える物理基礎
|B5判
|-
|707
|数研出版
|物理基礎
|A5判
|-
|708
|数研出版
|新編 物理基礎
|B5判
|-
|709
|第一学習社
|高等学校 物理基礎
|B5判変型
|-
|710
|第一学習社
|高等学校 新物理基礎
|B5判
|}
===物理===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|物理
|B5判変型
|-
|702
|実教出版
|物理
|B5判
|-
|703
|啓林館
|高等学校 物理
|A5判
|-
|704
|啓林館
|高等学校 総合物理1 様々な運動 熱 波
|A5判
|-
|705
|啓林館
|高等学校 総合物理2 電気と磁気 原子・分子の世界
|A5判
|-
|706
|数研出版
|物理
|A5判
|-
|707
|数研出版
|総合物理1 力と運動・熱
|A5判
|-
|708
|数研出版
|総合物理2 波・電気と磁気・原子
|A5判
|-
|709
|第一学習社
|高等学校 物理
|B5判変型
|}
===化学基礎===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学基礎
|B5判変型
|-
|702
|東京書籍
|新編化学基礎
|B5判
|-
|703
|実教出版
|化学基礎 academia
|A5判
|-
|704
|実教出版
|化学基礎
|B5判
|-
|705
|実教出版
|高校化学基礎
|B5判
|-
|706
|啓林館
|高等学校 化学基礎
|A5判
|-
|707
|啓林館
|i版 化学基礎
|AB判
|-
|708
|数研出版
|化学基礎
|A5判
|-
|709
|数研出版
|高等学校 化学基礎
|B5判変型
|-
|710
|数研出版
|新編 化学基礎
|B5判
|-
|711
|第一学習社
|高等学校 化学基礎
|B5判変型
|-
|712
|第一学習社
|高等学校 化学基礎
|B5判
|}
===化学===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学 Vol.1 理論編
|B5判変型
|-
|702
|東京書籍
|化学 Vol.2 物質編
|B5判変型
|-
|703
|実教出版
|化学 academia
|A5判
|-
|704
|実教出版
|化学
|B5判
|-
|705
|啓林館
|高等学校 化学
|A5判
|-
|706
|数研出版
|化学
|A5判
|-
|707
|数研出版
|新編 化学
|B5判
|-
|708
|第一学習社
|高等学校 化学
|B5判変型
|}
===生物基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|生物基礎
|B5判変型
|-
|702
|東京書籍
|新編生物基礎
|B5判
|-
|703
|実教出版
|生物基礎
|B5判
|-
|704
|実教出版
|高校生物基礎
|B5判
|-
|705
|啓林館
|高等学校 生物基礎
|B5判変型
|-
|706
|啓林館
|i版 生物基礎
|AB判
|-
|707
|数研出版
|生物基礎
|A5判
|-
|708
|数研出版
|高等学校 生物基礎
|B5判変型
|-
|709
|数研出版
|新編 生物基礎
|B5判
|-
|710
|第一学習社
|高等学校 生物基礎
|B5判変型
|-
|711
|第一学習社
|高等学校 新生物基礎
|B5判
|}
===生物===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||生物||B5判変型
|-
|702||実教出版||生物||B5判
|-
|703||啓林館||高等学校 生物||B5判変型
|-
|704||数研出版||生物||B5判変型
|-
|705||第一学習社||高等学校 生物||B5判変型
|}
===地学基礎===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||地学基礎||B5判
|-
|702||実教出版||地学基礎||B5判
|-
|703||啓林館||高等学校 地学基礎||B5判変型
|-
|704||数研出版||高等学校 地学基礎||B5判変型
|-
|705||第一学習社||高等学校 地学基礎||B5判
|}
===地学===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||啓林館||高等学校 地学||A5判
|}
== 保健体育 ==
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||大修館書店||現代高等保健育||B5判
|-
|702||大修館書店||新高等保健体育||B5判変型
|-
|703||第一学習社||高等学校 保健体育 Textbook||B5判
|-
|704||第一学習社||高等学校 保健体育 Activity||B5判
|}
== 芸術 ==
=== 音楽Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅰ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽1 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA1 || A4判
|-
| 704 || 音楽之友社 || ON! 1 || A4判変型
|}
=== 音楽Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅱ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽2 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA2 || A4判
|-
| 704 || 音楽之友社 || ON! 2 || A4判変型
|}
=== 美術Ⅰ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 ||美術1 || A4判変型
|-
| 702 ||日本文教出版 ||高校生の美術1 ||A4判
|-
| 703 || 日本文教出版 ||高校美術 ||A4判変型
|}
=== 美術Ⅱ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 || 美術2 ||A4判変型
|-
| 702 || 日本文教出版 || 高校生の美術2 ||A4判
|}
=== 工芸Ⅰ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅰ||A4判
|}
=== 工芸Ⅱ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅱ||A4判
|}
=== 書道Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅰ || A4判
|-
| 702 || 教育図書 || 書Ⅰ || A4判
|-
| 703 || 教育図書 || 書Ⅰプライマリーブック || A4判
|-
| 704 || 教育出版 || 書道Ⅰ || A4判
|-
| 705 || 光村図書出版 || 書Ⅰ || A4判
|}
=== 書道Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅱ || A4判
|-
| 702 || 教育図書 || 書Ⅱ || A4判
|-
| 703 || 教育出版 || 書道Ⅱ || A4判
|-
| 704 || 光村図書出版 || 書Ⅱ || A4判
|}
== 外国語 ==
=== 英語コミュニケーションⅠ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅰ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅠ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅠ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅠ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅠ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅠ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅠ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅠ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅠ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅰ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅰ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅰ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅰ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅰ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅰ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅰ
|AB判
|-
|719
|文英堂
|Grove English CommunicationⅠ
|B5判
|-
|720
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅰ
|B5判
|-
|721
|第一学習社
|CREATIVE English Communication Ⅰ
|B5判
|-
|722
|第一学習社
|Vivid English Communication Ⅰ
|B5判
|-
|723
|桐原書店
|Heartening English Communication Ⅰ
|B5判
|-
|724
|いいずな書店
|New Rays English Communication Ⅰ
|B5判変型
|-
|725
|Cambridge University Press & Assessment
|Cambridge Experience 1
|A4判
|}
=== 英語コミュニケーションⅡ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅱ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅡ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅡ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅡ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅡ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅡ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅡ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅡ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅡ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅱ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅱ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅱ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅱ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅱ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅱ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅱ
|AB判
|-
|718
|文英堂
|Grove English CommunicationⅡ
|B5判
|-
|719
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅱ
|B5判
|-
|720
|第一学習社
|CREATIVE English Communication Ⅱ
|B5判
|-
|721
|第一学習社
|Vivid English Communication Ⅱ
|B5判
|-
|722
|桐原書店
|Heartening English Communication Ⅱ
|B5判
|-
|723
|いいずな書店
|New Rays English Communication Ⅱ
|B5判変型
|-
|724
|Cambridge University Press & Assessment
|Cambridge Experience 2
|A4判
|}
=== 論理・表現Ⅰ ===
=== 論理・表現Ⅱ ===
== 家庭 ==
=== 家庭基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭基礎 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭基礎365 || AB判
|-
| 703 || 教育図書 || 家庭基礎 つながる暮らし 共に創る未来 || B5判
|-
| 704 || 教育図書 || Survive!! 高等学校 家庭基礎 || AB判
|-
| 705 || 実教出版 || 家庭基礎 気づく力 築く未来 || AB判
|-
| 706 || 実教出版 || Agenda家庭基礎 || B5判
|-
| 707 || 実教出版 || 図説家庭基礎 || AB判
|-
| 708 || 開隆堂 || 家庭基礎 明日の生活を築く || AB判
|-
| 709 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭基礎』で生活をつくろう || A4判
|-
| 710 || 第一学習社 || 高等学校 家庭基礎 持続可能な未来をつくる || AB判
|}
=== 家庭総合 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭総合 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭総合365 || AB判
|-
| 703 || 実教出版 || 家庭総合 || AB判
|-
| 704 || 開隆堂 || 家庭総合 明日の生活を築く || AB判
|-
| 705 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭総合』で生活をつくろう || A4判
|-
| 706 || 第一学習社 || 高等学校 家庭総合 持続可能な未来をつくる || AB判
|}
== 情報 ==
=== 情報Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新編情報Ⅰ || B5判
|-
| 702 || 東京書籍 || 情報Ⅰ Step Forward! || B5判
|-
| 703 || 実教出版 || 高校情報Ⅰ Python || B5判
|-
| 704 || 実教出版 || 高校情報Ⅰ JavaScript || B5判
|-
| 705 || 実教出版 || 最新情報Ⅰ || B5判
|-
| 706 || 実教出版 || 図説情報Ⅰ || AB判
|-
| 707 || 開隆堂 || 実践 情報Ⅰ || B5判
|-
| 708 || 数研出版 || 高等学校 情報Ⅰ || B5判
|-
| 709 || 数研出版 || 情報Ⅰ Next || B5判
|-
| 710 || 日本文教出版 || 情報Ⅰ || B5判変型
|-
| 711 || 日本文教出版 || 情報Ⅰ図解と実習-図解編 || B5判変型
|-
| 712 || 日本文教出版 || 情報Ⅰ図解と実習-実習編 || B5判変型
|-
| 713 || 第一学習社 || 高等学校 情報Ⅰ || AB判
|}
=== 情報Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 情報Ⅱ || B5判
|-
| 702 || 実教出版 || 情報Ⅱ || B5判
|-
| 703 || 日本文教出版 || 情報Ⅱ || B5判変型
|}
== 理数 ==
=== 理数探究基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 啓林館 || 理数探究基礎 未来に向かって || A4判
|-
| 702 || 数研出版 || 理数探究基礎 || B5判
|}
== 農業 ==
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|実教出版
|農業と環境
|B5判
|-
|702
|実教出版
|農業と情報
|B5判
|-
|708
|実教出版
|草花
|B5判
|-
|710
|実教出版
|栽培と環境
|B5判
|-
|709
|実教出版
|農業機械
|B5判
|-
|703
|実教出版
|植物バイオテクノロジー
|B5判
|-
|704
|実教出版
|食品製造
|B5判
|-
|711
|実教出版
|生物活用
|B5判
|-
|705
|実教出版
|森林科学
|B5判
|-
|712
|実教出版
|森林経営
|
|-
|706
|実教出版
|農業土木設計
|B5判
|-
|713
|東京電機大学
|農業土木施工
|B5判
|-
|707
|実教出版
|造園計画
|B5判
|-
|714
|東京電機大学
|造園施工管理
|B5判
|}
== 工業 ==
== 商業 ==
== 水産 ==
== 家庭 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || ファッションデザイン || B5判
|-
| 702 || 教育図書 || フードデザイン Food Changes LIFE || AB判
|-
| 703 || 実教出版 || フードデザイン || AB判
|-
| 704 || 実教出版 || 生活産業情報 || B5判
|-
| 705 || 実教出版 || ファッション造形基礎 || B5判
|-
| 706 || 教育図書 || 保育基礎 ようこそ、ともに育ち合う保育の世界へ || AB判
|-
| 707 || 実教出版 || 保育基礎 || B5判
|-
| 708 || 実教出版 || 消費生活 || B5判
|-
| 709 || 実教出版 || 保育実践 || B5判
|-
| 710 || 実教出版 || 服飾文化 || B5判
|}
== 看護 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 基礎看護 || B5判
|}
== 情報 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 情報産業と社会 || B5判
|-
| 702 || 実教出版 || 情報の表現と管理 || B5判
|-
| 703 || 東京電機大学 || 情報システムのプログラミング || B5判
|-
| 704 || 実教出版 || 情報セキュリティ || B5判
|-
| 705 || 実教出版 || 情報デザイン || B5判
|-
| 706 || 実教出版 || ネットワークシステム || B5判
|-
| 707 || 実教出版 || データベース || B5判
|}
== 福祉 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 社会福祉基礎 || B5判
|-
| 702 || 実教出版 || 介護福祉基礎 || B5判
|-
| 703 || 実教出版 || 生活支援技術 || B5判
|-
| 704 || 実教出版 || こころとからだの理解 || B5判
|}
==脚注==
*[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
8l4a8ge2kwzj5lkt4663vzneey9jj63
205816
205815
2022-07-25T05:52:49Z
Kwawe
68789
/* 論理・表現Ⅰ */
wikitext
text/x-wiki
{{Pathnav|メインページ|[[小学校・中学校・高等学校の学習]]>[[高等学校の学習]]>[[検定教科書]]|frame=1}}
このページでは、'''高等学校の教科書番号'''について説明します。教科書番号については、[[../|この上層ページ]]をご覧ください。
本内容は令和5年度以降の教科書目録をまとめています。
※以下、このページは新高校1年生から使う教科書を掲載しています。旧課程(現高校2~3年生)の教科書はこのページに掲載しておりません。
==国語==
※国語は本を読ますための性格なのか、A5版がほとんどです。
===現代の国語===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編現代の国語||A5判
|-
|702||東京書籍||精選現代の国語||A5判
|-
|703||東京書籍||現代の国語||A5判
|-
|704||三省堂||精選 現代の国語||A5判
|-
|705||三省堂||新 現代の国語||A5判
|-
|706||大修館書店||現代の国語||A5判
|-
|707||大修館書店||新編 現代の国語||B5判
|-
|708||数研出版||現代の国語||A5判
|-
|709||数研出版||高等学校 現代の国語||A5判
|-
|710||数研出版||新編 現代の国語||A5判
|-
|711||明治書院||精選 現代の国語||A5判
|-
|712||筑摩書房||現代の国語||A5判
|-
|713||第一学習社||高等学校 現代の国語||A5判
|-
|714||第一学習社||高等学校 精選現代の国語||A5判
|-
|715||第一学習社||高等学校 標準現代の国語||A5判
|-
|716||第一学習社||高等学校 新編現代の国語||B5判
|-
|717||桐原書店||探求 現代の国語||A5判
|-
|}
===言語文化===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編言語文化||A5判
|-
|702||東京書籍||精選言語文化||A5判
|-
|703||三省堂||精選 言語文化||A5判
|-
|704||三省堂||新 言語文化||A5判
|-
|705||大修館書店||言語文化||A5判
|-
|706||大修館書店||新編 言語文化||B5判
|-
|708||数研出版||高等学校 言語文化||A5判
|-
|709||数研出版||新編 言語文化||A5判
|-
|710||文英堂||言語文化||A5判
|-
|711||明治書院||精選言語文化||A5判
|-
|712||筑摩書房||言語文化||A5判
|-
|713||第一学習社||高等学校 言語文化||A5判
|-
|714||第一学習社||高等学校 精選言語文化||A5判
|-
|715||第一学習社||高等学校 標準言語文化||A5判
|-
|716||第一学習社||高等学校 新編言語文化||B5判
|-
|717||桐原書店||探求 言語文化||A5判
|}
===論理国語 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 論理国語 || A5判
|-
| 702 || 東京書籍 || 精選論理国語 || A5判
|-
| 703 || 三省堂 || 精選 論理国語 || A5判
|-
| 704 || 三省堂 || 新 論理国語 || A5判
|-
| 705 || 大修館書店 || |論理国語 || A5判
|-
| 706 || 大修館書店 || 新編 論理国語 || A5判
|-
| 707 || 数研出版 || 精選 論理国語 || A5判
|-
| 708 || 数研出版 || 論理国語 || A5判
|-
| 709 || 明治書院 || 精選 論理国語 || A5判
|-
| 710 || 筑摩書房 || 論理国語 || A5判
|-
| 711 || 第一学習社 || 高等学校 論理国語 || A5判
|-
| 712|| 第一学習社 || 高等学校 標準論理国語 || A5判
|-
| 713 || 桐原書店 || 探求 論理国語 || A5判
|}
===文学国語===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 文学国語 || A5判
|-
| 702 || 三省堂 || 精選 文学国語 || A5判
|-
| 703 || 三省堂 || 新 文学国語 || A5判
|-
| 704 || 大修館書店 || |文学国語 || A5判
|-
| 705 || 大修館書店 || 新編 文学国語 || A5判
|-
| 706 || 数研出版 || 文学国語 || A5判
|-
| 707 || 明治書院 || 精選 文学国語 || A5判
|-
| 708 || 筑摩書房 || 文学国語 || A5判
|-
| 709 || 第一学習社 || 高等学校 文学国語 || A5判
|-
| 710 || 第一学習社 || 高等学校 標準文学国語 || A5判
|-
| 711 || 桐原書店 || 探求 文学国語 || A5判
|}
===国語表現===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 大修館書店 || 国語表現 || B5判
|}
===古典探究 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社!! 教科書名!! 判型
|-
| 701 || 東京書籍 ||新編古典探究 || A5判
|-
| 702 || 東京書籍 ||精選古典探究 古文編 || A5判
|-
| 703 || 東京書籍 ||精選古典探究 漢文編 || A5判
|-
| 704 || 三省堂 ||精選 古典探究 古文編 || A5判
|-
| 705 || 三省堂 ||精選 古典探究 漢文編 || A5判
|-
| 706 || 大修館書店 ||古典探究 古文編 || A5判
|-
| 707 || 大修館書店 ||古典探究 漢文編 || A5判
|-
| 708 || 大修館書店 ||精選 古典探究 || A5判
|-
| 709 || 数研出版 ||古典探究 古文編 || A5判
|-
| 710 || 数研出版 ||古典探究 漢文編 || A5判
|-
| 711 || 数研出版 ||高等学校 古典探究 || A5判
|-
| 712 || 文英堂 ||古典探究 || A5判
|-
| 713 || 明治書院 ||精選 古典探究 古文編|| A5判
|-
| 714 || 明治書院 ||精選 古典探究 漢文編 || A5判
|-
| 715 || 筑摩書房 ||古典探究 古文編 || A5判
|-
| 716 || 筑摩書房 ||古典探究 漢文編 || A5判
|-
| 717 || 第一学習社 ||高等学校 古典探究 古文編 || A5判
|-
| 718 || 第一学習社 || 高等学校 古典探究 漢文編 || A5判
|-
| 719 || 第一学習社 || 高等学校 精選古典探究 || A5判
|-
| 720 || 第一学習社 || 高等学校 標準古典探究 || A5判
|-
| 721 || 桐原書店 || 探求 古典探究 古文編 || A5判
|-
| 722 || 桐原書店 || 探求 古典探究 漢文編 || A5判
|}
==地理歴史==
===地理総合===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 地理総合 || AB判
|-
| 702 || 実教出版 || 地理総合 || AB判
|-
| 703 || 帝国書院 || 高等学校 地理総合 || AB判
|-
| 704 || 二宮書店 || 地理総合 世界に学び地域へつなぐ || B5判
|-
| 705 || 二宮書店 || わたしたちの地理総合 世界から日本へ || AB判
|-
| 706 || 第一学習社 || 高等学校 地理総合 世界を学び、地域をつくる || AB判
|-
| 707 || 帝国書院 || 高校生の地理総合 || AB判
|}
===地理探究===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
| 701 ||東京書籍||地理探究||AB判
|-
|702||帝国書院||新詳地理探究||B5判
|-
|703||二宮書店|| 地理探究||B5判
|}
===歴史総合===
{| class="wikitable sortable"
|-
! 番号!! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新選歴史総合 || AB判
|-
| 702 || 東京書籍 || 詳解歴史総合 || B5判
|-
| 703 || 実教出版 || 詳述歴史総合 || B5判
|-
| 704 || 実教出版 || 歴史総合 || AB判
|-
| 705 || 清水書院 || 私たちの歴史総合 || A4判
|-
| 706 || 帝国書院 || 明解 歴史総合 || AB判
|-
| 707 || 山川出版社 || 歴史総合 近代から現代へ || B5判
|-
| 708 || 山川出版社 || 現代の歴史総合 みる・読みとく・考える || AB判
|-
| 709 || 山川出版社 || わたしたちの歴史 日本から世界へ || AB判
|-
| 710 || 第一学習社 || 高等学校 歴史総合 || AB判
|-
| 711 || 第一学習社 || 高等学校 新歴史総合 過去との対話、つなぐ未来 || AB判
|-
| 712 || 明成社 || 私たちの歴史総合 || B5判
|}
===日本史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 日本史探究 || B5判
|-
| 702 || 実教出版 || 日本史探究 || B5判変型
|-
| 703 || 実教出版 ||精選日本史探究 今につなぐ 未来をえがく || AB判
|-
| 704 || 清水書院 || 高等学校 日本史探究 || B5判
|-
| 705 || 山川出版社 || 詳説日本史 || B5判変型
|-
| 706 || 山川出版社 || 高校日本史|| B5判
|-
| 707 || 第一学習社 || 高等学校 日本史探究 || B5判
|}
===世界史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 世界史探究 || B5判
|-
| 702 || 実教出版 || 世界史探究 || B5判変型
|-
| 703 || 帝国書院 || 新詳世界史探究 || B5判
|-
| 704 || 山川出版社 || 詳説世界史 || B5判変型
|-
| 705 || 山川出版社 || 高校世界史 || B5判
|-
| 706 || 山川出版社 || 新世界史 || B5判変型
|-
| 707 || 第一学習社 || 高等学校 世界史探究 || B5判
|}
===地図===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新高等地図 || A4判
|-
| 702 || 帝国書院 || 新詳高等地図 || AB判
|-
| 703 || 帝国書院 || 標準高等地図 || A4判
|-
| 704 || 二宮書店 || 高等地図帳 || B5判
|-
| 705 || 二宮書店 || 詳解現代地図 最新版 || AB判
|-
| 706 || 二宮書店 || 基本地図帳 || A4判
|-
| 707 || 二宮書店 || コンパクト地理総合地図 || AB判変型
|}
==公民==
===公共===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||公共||AB判
|-
|702||教育図書||公共||B5判
|-
|703||実教出版||詳述公共||A5判
|-
|704||実教出版||公共||B5判
|-
|705||清水書院||高等学校 公共||B5判
|-
|706||清水書院||私たちの公共||AB判
|-
|707||帝国書院||高等学校 公共||AB判
|-
|708||数研出版||公共(令和4年度)||
|-
|709||数研出版||高等学校 公共 これからの社会について考える||AB判
|-
|710||第一学習社||高等学校 公共||B5判
|-
|711||第一学習社||高等学校 新公共||AB判
|-
|712||東京法令出版||公共||B5判
|-
|713||数研出版||新版 公共(令和5年度)||B5判
|}
===倫理===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 倫理 || B5判変型
|-
| 702 || 実教出版 || 詳述倫理 || A5判
|-
| 703 || 清水書院 || 高等学校 新倫理 || A5判
|-
| 704 || 数研出版 || 倫理 || A5判
|-
| 705 || 第一学習社 || 高等学校 倫理 || B5判
|}
===政治・経済===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
|701||東京書籍||政治・経済||B5判変型
|-
|702||実教出版||詳述政治・経済||A5判
|-
|703||実教出版||最新政治・経済||B5判
|-
|704||清水書院||高等学校 政治・経済||A5判
|-
|705||数研出版||政治・経済||A5判
|-
|706||第一学習社||高等学校 政治・経済||B5判
|}
==数学==
===数学Ⅰ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅰ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅰ Standard || A5判
|-
| 703 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学Ⅰ || B5判
|-
| 705 || 東京書籍 || 新数学Ⅰ 解答編 || B5判
|-
| 706 || 実教出版 || 数学Ⅰ Progress || A5判
|-
| 707 || 実教出版 || 新編数学Ⅰ || A5判
|-
| 708|| 実教出版 || 高校数学Ⅰ || B5判
|-
| 709 || 啓林館 || 数学Ⅰ || A5判
|-
| 710 || 啓林館 || 新編数学Ⅰ || A5判
|-
| 711 || 啓林館 || 深進数学Ⅰ || A5判
|-
| 712 || 数研出版 || 数学Ⅰ || A5判
|-
| 713 || 数研出版 || 高等学校 数学Ⅰ || A5判
|-
| 714 || 数研出版 || 新編 数学Ⅰ || A5判
|-
| 715 || 数研出版 || 最新 数学Ⅰ || A5判
|-
| 716 || 数研出版 || 新 高校の数学Ⅰ || B5判
|-
| 717 ||数研出版 || NEXT 数学Ⅰ || A5判
|-
| 718 || 第一学習社|| 新編数学Ⅰ || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Ⅰサポートブック || B5判変型版
|}
===数学Ⅱ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅱ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅱ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅱ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅱ || A5判
|-
| 705|| 実教出版 || 高校数学Ⅱ || B5判
|-
| 706 || 啓林館 || 数学Ⅱ || A5判
|-
| 707 || 啓林館 || 新編数学Ⅱ || A5判
|-
| 708 || 啓林館 || 深進数学Ⅱ || A5判
|-
| 709 || 数研出版 || 数学Ⅱ || A5判
|-
| 710 || 数研出版 || 高等学校 数学Ⅱ || A5判
|-
| 711 || 数研出版 || 新編 数学Ⅱ || A5判
|-
| 712 || 数研出版 || 最新 数学Ⅱ || A5判
|-
| 713 ||数研出版 || NEXT 数学Ⅱ || A5判
|-
| 714 || 第一学習社|| 新編数学Ⅱ || B5判変型版
|-
| 715 || 第一学習社 || 新編数学Ⅱサポートブック || B5判変型版
|-
| 716 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 717 || 東京書籍 || 新数学Ⅱ || B5判
|-
| 718 || 東京書籍 || 新数学Ⅱ 解答編 || B5判
|-
| 719 || 数研出版 || 新 高校の数学Ⅱ || B5判
|}
===数学Ⅲ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅲ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅲ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅲ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅲ || A5判
|-
| 705 || 啓林館 || 数学Ⅲ || A5判
|-
| 706 || 啓林館 || 新編数学Ⅲ || A5判
|-
| 707 || 啓林館 || 深進数学Ⅲ || A5判
|-
| 708 || 数研出版 || 数学Ⅲ || A5判
|-
| 709 || 数研出版 || 高等学校 数学Ⅲ || A5判
|-
| 710 || 数研出版 || 新編 数学Ⅲ || A5判
|-
| 711 || 数研出版 || 最新 数学Ⅲ || A5判
|-
| 712 ||数研出版 || NEXT 数学Ⅲ || A5判
|}
===数学A===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学A Advanced || A5判
|-
| 702 || 東京書籍 || 数学A Standard || A5判
|-
| 703 || 東京書籍 || 数学A Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学A || B5判
|-
| 705 || 東京書籍 || 新数学A 解答編 || B5判
|-
| 706 || 実教出版 || 数学A Progress || A5判
|-
| 707 || 実教出版 || 新編数学A || A5判
|-
| 708|| 実教出版 || 高校数学A || B5判
|-
| 709 || 啓林館 || 数学A || A5判
|-
| 710 || 啓林館 || 新編数学A || A5判
|-
| 711 || 啓林館 || 深進数学A || A5判
|-
| 712 || 数研出版 || 数学A || A5判
|-
| 713 || 数研出版 || 高等学校 数学A || A5判
|-
| 714 || 数研出版 || 新編 数学A || A5判
|-
| 715 || 数研出版 || 最新 数学A || A5判
|-
| 716 || 数研出版 || 新 高校の数学A || B5判
|-
| 717 ||数研出版 || NEXT 数学A || A5判
|-
| 718 || 第一学習社|| 新編数学A || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Aサポートブック || B5判変型版
|}
===数学B===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学B Advanced || A5判
|-
| 702 || 東京書籍 || 数学B Standard || A5判
|-
| 703 || 東京書籍 || 数学B Essence || B5判変型版
|-
| 704 || 実教出版 || 数学B Progress || A5判
|-
| 705 || 実教出版 || 新編数学B || A5判
|-
| 706|| 実教出版 || 高校数学B || B5判
|-
| 707 || 啓林館 || 数学B || A5判
|-
| 708 || 啓林館 || 新編数学B || A5判
|-
| 709 || 啓林館 || 深進数学B || A5判
|-
| 710 || 数研出版 || 数学B || A5判
|-
| 711 || 数研出版 || 高等学校 数学B || A5判
|-
| 712 || 数研出版 || 新編 数学B || A5判
|-
| 713 || 数研出版 || 最新 数学B || A5判
|-
| 714 || 数研出版 || 新 高校の数学B || B5判
|-
| 715 ||数研出版 || NEXT 数学B || A5判
|-
| 716 || 第一学習社|| 新編数学B || B5判変型版
|}
===数学C===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学C Advanced || A5判
|-
| 702 || 東京書籍 || 数学C Standard || A5判
|-
| 703 || 実教出版 || 数学C Progress || A5判
|-
| 704 || 実教出版 || 新編数学C || A5判
|-
| 705 || 啓林館 || 数学C || A5判
|-
| 706 || 啓林館 || 新編数学C || A5判
|-
| 707 || 啓林館 || 深進数学C || A5判
|-
| 708 || 数研出版 || 数学C || A5判
|-
| 709 || 数研出版 || 高等学校 数学C || A5判
|-
| 710 || 数研出版 || 新編 数学C || A5判
|-
| 711 || 数研出版 || 最新 数学C || A5判
|-
| 712 || 数研出版 || NEXT 数学C || A5判
|-
| 713 || 第一学習社 || 新編数学C || B5判変型
|}
==理科==
===科学と人間生活===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 科学と人間生活 || B5判変型
|-
| 702 || 実教出版 || 科学と人間生活 || B5判
|-
| 703 || 啓林館 || 高等学校 科学と人間生活 || B5判
|-
| 704 || 数研出版 || 科学と人間生活 || AB判
|-
| 705 || 第一学習社 || 高等学校 科学と人間生活 || B5判
|}
===物理基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|物理基礎
|B5判変型
|-
|702
|東京書籍
|新編物理基礎
|B5判
|-
|703
|実教出版
|物理基礎
|B5判
|-
|704
|実教出版
|高校物理基礎
|B5判
|-
|705
|啓林館
|高等学校 物理基礎
|A5判
|-
|706
|啓林館
|高等学校 考える物理基礎
|B5判
|-
|707
|数研出版
|物理基礎
|A5判
|-
|708
|数研出版
|新編 物理基礎
|B5判
|-
|709
|第一学習社
|高等学校 物理基礎
|B5判変型
|-
|710
|第一学習社
|高等学校 新物理基礎
|B5判
|}
===物理===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|物理
|B5判変型
|-
|702
|実教出版
|物理
|B5判
|-
|703
|啓林館
|高等学校 物理
|A5判
|-
|704
|啓林館
|高等学校 総合物理1 様々な運動 熱 波
|A5判
|-
|705
|啓林館
|高等学校 総合物理2 電気と磁気 原子・分子の世界
|A5判
|-
|706
|数研出版
|物理
|A5判
|-
|707
|数研出版
|総合物理1 力と運動・熱
|A5判
|-
|708
|数研出版
|総合物理2 波・電気と磁気・原子
|A5判
|-
|709
|第一学習社
|高等学校 物理
|B5判変型
|}
===化学基礎===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学基礎
|B5判変型
|-
|702
|東京書籍
|新編化学基礎
|B5判
|-
|703
|実教出版
|化学基礎 academia
|A5判
|-
|704
|実教出版
|化学基礎
|B5判
|-
|705
|実教出版
|高校化学基礎
|B5判
|-
|706
|啓林館
|高等学校 化学基礎
|A5判
|-
|707
|啓林館
|i版 化学基礎
|AB判
|-
|708
|数研出版
|化学基礎
|A5判
|-
|709
|数研出版
|高等学校 化学基礎
|B5判変型
|-
|710
|数研出版
|新編 化学基礎
|B5判
|-
|711
|第一学習社
|高等学校 化学基礎
|B5判変型
|-
|712
|第一学習社
|高等学校 化学基礎
|B5判
|}
===化学===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学 Vol.1 理論編
|B5判変型
|-
|702
|東京書籍
|化学 Vol.2 物質編
|B5判変型
|-
|703
|実教出版
|化学 academia
|A5判
|-
|704
|実教出版
|化学
|B5判
|-
|705
|啓林館
|高等学校 化学
|A5判
|-
|706
|数研出版
|化学
|A5判
|-
|707
|数研出版
|新編 化学
|B5判
|-
|708
|第一学習社
|高等学校 化学
|B5判変型
|}
===生物基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|生物基礎
|B5判変型
|-
|702
|東京書籍
|新編生物基礎
|B5判
|-
|703
|実教出版
|生物基礎
|B5判
|-
|704
|実教出版
|高校生物基礎
|B5判
|-
|705
|啓林館
|高等学校 生物基礎
|B5判変型
|-
|706
|啓林館
|i版 生物基礎
|AB判
|-
|707
|数研出版
|生物基礎
|A5判
|-
|708
|数研出版
|高等学校 生物基礎
|B5判変型
|-
|709
|数研出版
|新編 生物基礎
|B5判
|-
|710
|第一学習社
|高等学校 生物基礎
|B5判変型
|-
|711
|第一学習社
|高等学校 新生物基礎
|B5判
|}
===生物===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||生物||B5判変型
|-
|702||実教出版||生物||B5判
|-
|703||啓林館||高等学校 生物||B5判変型
|-
|704||数研出版||生物||B5判変型
|-
|705||第一学習社||高等学校 生物||B5判変型
|}
===地学基礎===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||地学基礎||B5判
|-
|702||実教出版||地学基礎||B5判
|-
|703||啓林館||高等学校 地学基礎||B5判変型
|-
|704||数研出版||高等学校 地学基礎||B5判変型
|-
|705||第一学習社||高等学校 地学基礎||B5判
|}
===地学===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||啓林館||高等学校 地学||A5判
|}
== 保健体育 ==
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||大修館書店||現代高等保健育||B5判
|-
|702||大修館書店||新高等保健体育||B5判変型
|-
|703||第一学習社||高等学校 保健体育 Textbook||B5判
|-
|704||第一学習社||高等学校 保健体育 Activity||B5判
|}
== 芸術 ==
=== 音楽Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅰ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽1 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA1 || A4判
|-
| 704 || 音楽之友社 || ON! 1 || A4判変型
|}
=== 音楽Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅱ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽2 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA2 || A4判
|-
| 704 || 音楽之友社 || ON! 2 || A4判変型
|}
=== 美術Ⅰ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 ||美術1 || A4判変型
|-
| 702 ||日本文教出版 ||高校生の美術1 ||A4判
|-
| 703 || 日本文教出版 ||高校美術 ||A4判変型
|}
=== 美術Ⅱ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 || 美術2 ||A4判変型
|-
| 702 || 日本文教出版 || 高校生の美術2 ||A4判
|}
=== 工芸Ⅰ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅰ||A4判
|}
=== 工芸Ⅱ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅱ||A4判
|}
=== 書道Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅰ || A4判
|-
| 702 || 教育図書 || 書Ⅰ || A4判
|-
| 703 || 教育図書 || 書Ⅰプライマリーブック || A4判
|-
| 704 || 教育出版 || 書道Ⅰ || A4判
|-
| 705 || 光村図書出版 || 書Ⅰ || A4判
|}
=== 書道Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅱ || A4判
|-
| 702 || 教育図書 || 書Ⅱ || A4判
|-
| 703 || 教育出版 || 書道Ⅱ || A4判
|-
| 704 || 光村図書出版 || 書Ⅱ || A4判
|}
== 外国語 ==
=== 英語コミュニケーションⅠ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅰ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅠ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅠ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅠ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅠ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅠ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅠ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅠ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅠ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅰ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅰ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅰ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅰ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅰ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅰ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅰ
|AB判
|-
|719
|文英堂
|Grove English CommunicationⅠ
|B5判
|-
|720
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅰ
|B5判
|-
|721
|第一学習社
|CREATIVE English Communication Ⅰ
|B5判
|-
|722
|第一学習社
|Vivid English Communication Ⅰ
|B5判
|-
|723
|桐原書店
|Heartening English Communication Ⅰ
|B5判
|-
|724
|いいずな書店
|New Rays English Communication Ⅰ
|B5判変型
|-
|725
|Cambridge University Press & Assessment
|Cambridge Experience 1
|A4判
|}
=== 英語コミュニケーションⅡ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅱ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅡ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅡ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅡ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅡ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅡ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅡ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅡ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅡ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅱ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅱ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅱ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅱ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅱ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅱ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅱ
|AB判
|-
|718
|文英堂
|Grove English CommunicationⅡ
|B5判
|-
|719
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅱ
|B5判
|-
|720
|第一学習社
|CREATIVE English Communication Ⅱ
|B5判
|-
|721
|第一学習社
|Vivid English Communication Ⅱ
|B5判
|-
|722
|桐原書店
|Heartening English Communication Ⅱ
|B5判
|-
|723
|いいずな書店
|New Rays English Communication Ⅱ
|B5判変型
|-
|724
|Cambridge University Press & Assessment
|Cambridge Experience 2
|A4判
|}
=== 論理・表現Ⅰ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|NEW FAVORITE English Logic and Expression Ⅰ
|B5判
|-
|702
|開隆堂
|Amity English Logic and Expression Ⅰ
|A4判
|-
|703
|開隆堂
|APPLAUSE ENGLISH LOGIC AND EXPRESSION Ⅰ
|B5判
|-
|704
|三省堂
|CROWN Logic and ExpressionⅠ
|B5判
|-
|705
|三省堂
|MY WAY Logic and ExpressionⅠ
|B5判
|-
|706
|三省堂
|VISTA Logic and ExpressionⅠ
|B5判
|-
|707
|大修館書店
|Genius English Logic and Expression Ⅰ
|B5判
|-
|708
|啓林館
|Vision Quest English Logic and Expression Ⅰ Advanced
|B5判
|-
|709
|啓林館
|Vision Quest English Logic and Expression Ⅰ Standard
|B5判
|-
|710
|数研出版
|EARTHRISE English Logic and Expression Ⅰ Advanced
|B5判
|-
|711
|数研出版
|EARTHRISE English Logic and Expression Ⅰ Standard
|B5判
|-
|712
|数研出版
|BIG DIPPER English Logic and Expression Ⅰ
|B5判
|-
|713
|増進堂
|MAINSTREAM English Logic and Expression Ⅰ
|B5判
|-
|714
|桐原書店
|FACTBOOK English Logic and Expression Ⅰ
|B5判
|-
|715
|CHEERS
|ATLANTIS Logic and ExpressionⅠStandard
|B5判
|-
|716
|いいずな書店
|Harmony English Logic and Expression Ⅰ
|AB判
|-
|717
|いいずな書店
|be English Logic and Expression Ⅰ Clear
|B5判
|-
|718
|いいずな書店
|be English Logic and Expression Ⅰ Smart
|B5判
|}
=== 論理・表現Ⅱ ===
== 家庭 ==
=== 家庭基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭基礎 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭基礎365 || AB判
|-
| 703 || 教育図書 || 家庭基礎 つながる暮らし 共に創る未来 || B5判
|-
| 704 || 教育図書 || Survive!! 高等学校 家庭基礎 || AB判
|-
| 705 || 実教出版 || 家庭基礎 気づく力 築く未来 || AB判
|-
| 706 || 実教出版 || Agenda家庭基礎 || B5判
|-
| 707 || 実教出版 || 図説家庭基礎 || AB判
|-
| 708 || 開隆堂 || 家庭基礎 明日の生活を築く || AB判
|-
| 709 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭基礎』で生活をつくろう || A4判
|-
| 710 || 第一学習社 || 高等学校 家庭基礎 持続可能な未来をつくる || AB判
|}
=== 家庭総合 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭総合 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭総合365 || AB判
|-
| 703 || 実教出版 || 家庭総合 || AB判
|-
| 704 || 開隆堂 || 家庭総合 明日の生活を築く || AB判
|-
| 705 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭総合』で生活をつくろう || A4判
|-
| 706 || 第一学習社 || 高等学校 家庭総合 持続可能な未来をつくる || AB判
|}
== 情報 ==
=== 情報Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新編情報Ⅰ || B5判
|-
| 702 || 東京書籍 || 情報Ⅰ Step Forward! || B5判
|-
| 703 || 実教出版 || 高校情報Ⅰ Python || B5判
|-
| 704 || 実教出版 || 高校情報Ⅰ JavaScript || B5判
|-
| 705 || 実教出版 || 最新情報Ⅰ || B5判
|-
| 706 || 実教出版 || 図説情報Ⅰ || AB判
|-
| 707 || 開隆堂 || 実践 情報Ⅰ || B5判
|-
| 708 || 数研出版 || 高等学校 情報Ⅰ || B5判
|-
| 709 || 数研出版 || 情報Ⅰ Next || B5判
|-
| 710 || 日本文教出版 || 情報Ⅰ || B5判変型
|-
| 711 || 日本文教出版 || 情報Ⅰ図解と実習-図解編 || B5判変型
|-
| 712 || 日本文教出版 || 情報Ⅰ図解と実習-実習編 || B5判変型
|-
| 713 || 第一学習社 || 高等学校 情報Ⅰ || AB判
|}
=== 情報Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 情報Ⅱ || B5判
|-
| 702 || 実教出版 || 情報Ⅱ || B5判
|-
| 703 || 日本文教出版 || 情報Ⅱ || B5判変型
|}
== 理数 ==
=== 理数探究基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 啓林館 || 理数探究基礎 未来に向かって || A4判
|-
| 702 || 数研出版 || 理数探究基礎 || B5判
|}
== 農業 ==
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|実教出版
|農業と環境
|B5判
|-
|702
|実教出版
|農業と情報
|B5判
|-
|708
|実教出版
|草花
|B5判
|-
|710
|実教出版
|栽培と環境
|B5判
|-
|709
|実教出版
|農業機械
|B5判
|-
|703
|実教出版
|植物バイオテクノロジー
|B5判
|-
|704
|実教出版
|食品製造
|B5判
|-
|711
|実教出版
|生物活用
|B5判
|-
|705
|実教出版
|森林科学
|B5判
|-
|712
|実教出版
|森林経営
|
|-
|706
|実教出版
|農業土木設計
|B5判
|-
|713
|東京電機大学
|農業土木施工
|B5判
|-
|707
|実教出版
|造園計画
|B5判
|-
|714
|東京電機大学
|造園施工管理
|B5判
|}
== 工業 ==
== 商業 ==
== 水産 ==
== 家庭 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || ファッションデザイン || B5判
|-
| 702 || 教育図書 || フードデザイン Food Changes LIFE || AB判
|-
| 703 || 実教出版 || フードデザイン || AB判
|-
| 704 || 実教出版 || 生活産業情報 || B5判
|-
| 705 || 実教出版 || ファッション造形基礎 || B5判
|-
| 706 || 教育図書 || 保育基礎 ようこそ、ともに育ち合う保育の世界へ || AB判
|-
| 707 || 実教出版 || 保育基礎 || B5判
|-
| 708 || 実教出版 || 消費生活 || B5判
|-
| 709 || 実教出版 || 保育実践 || B5判
|-
| 710 || 実教出版 || 服飾文化 || B5判
|}
== 看護 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 基礎看護 || B5判
|}
== 情報 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 情報産業と社会 || B5判
|-
| 702 || 実教出版 || 情報の表現と管理 || B5判
|-
| 703 || 東京電機大学 || 情報システムのプログラミング || B5判
|-
| 704 || 実教出版 || 情報セキュリティ || B5判
|-
| 705 || 実教出版 || 情報デザイン || B5判
|-
| 706 || 実教出版 || ネットワークシステム || B5判
|-
| 707 || 実教出版 || データベース || B5判
|}
== 福祉 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 社会福祉基礎 || B5判
|-
| 702 || 実教出版 || 介護福祉基礎 || B5判
|-
| 703 || 実教出版 || 生活支援技術 || B5判
|-
| 704 || 実教出版 || こころとからだの理解 || B5判
|}
==脚注==
*[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
1x74vbi29053yqzmog6mj3wnzk5ur1u
205817
205816
2022-07-25T05:55:53Z
Kwawe
68789
wikitext
text/x-wiki
{{Pathnav|メインページ|[[小学校・中学校・高等学校の学習]]>[[高等学校の学習]]>[[検定教科書]]|frame=1}}
このページでは、'''高等学校の教科書番号'''について説明します。教科書番号については、[[../|この上層ページ]]をご覧ください。
本内容は令和5年度以降の教科書目録をまとめています。
※以下、このページは新高校1年生から使う教科書を掲載しています。旧課程(現高校2~3年生)の教科書はこのページに掲載しておりません。
==国語==
※国語は本を読ますための性格なのか、A5版がほとんどです。
===現代の国語===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編現代の国語||A5判
|-
|702||東京書籍||精選現代の国語||A5判
|-
|703||東京書籍||現代の国語||A5判
|-
|704||三省堂||精選 現代の国語||A5判
|-
|705||三省堂||新 現代の国語||A5判
|-
|706||大修館書店||現代の国語||A5判
|-
|707||大修館書店||新編 現代の国語||B5判
|-
|708||数研出版||現代の国語||A5判
|-
|709||数研出版||高等学校 現代の国語||A5判
|-
|710||数研出版||新編 現代の国語||A5判
|-
|711||明治書院||精選 現代の国語||A5判
|-
|712||筑摩書房||現代の国語||A5判
|-
|713||第一学習社||高等学校 現代の国語||A5判
|-
|714||第一学習社||高等学校 精選現代の国語||A5判
|-
|715||第一学習社||高等学校 標準現代の国語||A5判
|-
|716||第一学習社||高等学校 新編現代の国語||B5判
|-
|717||桐原書店||探求 現代の国語||A5判
|-
|}
===言語文化===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||新編言語文化||A5判
|-
|702||東京書籍||精選言語文化||A5判
|-
|703||三省堂||精選 言語文化||A5判
|-
|704||三省堂||新 言語文化||A5判
|-
|705||大修館書店||言語文化||A5判
|-
|706||大修館書店||新編 言語文化||B5判
|-
|708||数研出版||高等学校 言語文化||A5判
|-
|709||数研出版||新編 言語文化||A5判
|-
|710||文英堂||言語文化||A5判
|-
|711||明治書院||精選言語文化||A5判
|-
|712||筑摩書房||言語文化||A5判
|-
|713||第一学習社||高等学校 言語文化||A5判
|-
|714||第一学習社||高等学校 精選言語文化||A5判
|-
|715||第一学習社||高等学校 標準言語文化||A5判
|-
|716||第一学習社||高等学校 新編言語文化||B5判
|-
|717||桐原書店||探求 言語文化||A5判
|}
===論理国語 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 論理国語 || A5判
|-
| 702 || 東京書籍 || 精選論理国語 || A5判
|-
| 703 || 三省堂 || 精選 論理国語 || A5判
|-
| 704 || 三省堂 || 新 論理国語 || A5判
|-
| 705 || 大修館書店 || |論理国語 || A5判
|-
| 706 || 大修館書店 || 新編 論理国語 || A5判
|-
| 707 || 数研出版 || 精選 論理国語 || A5判
|-
| 708 || 数研出版 || 論理国語 || A5判
|-
| 709 || 明治書院 || 精選 論理国語 || A5判
|-
| 710 || 筑摩書房 || 論理国語 || A5判
|-
| 711 || 第一学習社 || 高等学校 論理国語 || A5判
|-
| 712|| 第一学習社 || 高等学校 標準論理国語 || A5判
|-
| 713 || 桐原書店 || 探求 論理国語 || A5判
|}
===文学国語===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 文学国語 || A5判
|-
| 702 || 三省堂 || 精選 文学国語 || A5判
|-
| 703 || 三省堂 || 新 文学国語 || A5判
|-
| 704 || 大修館書店 || |文学国語 || A5判
|-
| 705 || 大修館書店 || 新編 文学国語 || A5判
|-
| 706 || 数研出版 || 文学国語 || A5判
|-
| 707 || 明治書院 || 精選 文学国語 || A5判
|-
| 708 || 筑摩書房 || 文学国語 || A5判
|-
| 709 || 第一学習社 || 高等学校 文学国語 || A5判
|-
| 710 || 第一学習社 || 高等学校 標準文学国語 || A5判
|-
| 711 || 桐原書店 || 探求 文学国語 || A5判
|}
===国語表現===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 大修館書店 || 国語表現 || B5判
|}
===古典探究 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社!! 教科書名!! 判型
|-
| 701 || 東京書籍 ||新編古典探究 || A5判
|-
| 702 || 東京書籍 ||精選古典探究 古文編 || A5判
|-
| 703 || 東京書籍 ||精選古典探究 漢文編 || A5判
|-
| 704 || 三省堂 ||精選 古典探究 古文編 || A5判
|-
| 705 || 三省堂 ||精選 古典探究 漢文編 || A5判
|-
| 706 || 大修館書店 ||古典探究 古文編 || A5判
|-
| 707 || 大修館書店 ||古典探究 漢文編 || A5判
|-
| 708 || 大修館書店 ||精選 古典探究 || A5判
|-
| 709 || 数研出版 ||古典探究 古文編 || A5判
|-
| 710 || 数研出版 ||古典探究 漢文編 || A5判
|-
| 711 || 数研出版 ||高等学校 古典探究 || A5判
|-
| 712 || 文英堂 ||古典探究 || A5判
|-
| 713 || 明治書院 ||精選 古典探究 古文編|| A5判
|-
| 714 || 明治書院 ||精選 古典探究 漢文編 || A5判
|-
| 715 || 筑摩書房 ||古典探究 古文編 || A5判
|-
| 716 || 筑摩書房 ||古典探究 漢文編 || A5判
|-
| 717 || 第一学習社 ||高等学校 古典探究 古文編 || A5判
|-
| 718 || 第一学習社 || 高等学校 古典探究 漢文編 || A5判
|-
| 719 || 第一学習社 || 高等学校 精選古典探究 || A5判
|-
| 720 || 第一学習社 || 高等学校 標準古典探究 || A5判
|-
| 721 || 桐原書店 || 探求 古典探究 古文編 || A5判
|-
| 722 || 桐原書店 || 探求 古典探究 漢文編 || A5判
|}
==地理歴史==
===地理総合===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 地理総合 || AB判
|-
| 702 || 実教出版 || 地理総合 || AB判
|-
| 703 || 帝国書院 || 高等学校 地理総合 || AB判
|-
| 704 || 二宮書店 || 地理総合 世界に学び地域へつなぐ || B5判
|-
| 705 || 二宮書店 || わたしたちの地理総合 世界から日本へ || AB判
|-
| 706 || 第一学習社 || 高等学校 地理総合 世界を学び、地域をつくる || AB判
|-
| 707 || 帝国書院 || 高校生の地理総合 || AB判
|}
===地理探究===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
| 701 ||東京書籍||地理探究||AB判
|-
|702||帝国書院||新詳地理探究||B5判
|-
|703||二宮書店|| 地理探究||B5判
|}
===歴史総合===
{| class="wikitable sortable"
|-
! 番号!! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新選歴史総合 || AB判
|-
| 702 || 東京書籍 || 詳解歴史総合 || B5判
|-
| 703 || 実教出版 || 詳述歴史総合 || B5判
|-
| 704 || 実教出版 || 歴史総合 || AB判
|-
| 705 || 清水書院 || 私たちの歴史総合 || A4判
|-
| 706 || 帝国書院 || 明解 歴史総合 || AB判
|-
| 707 || 山川出版社 || 歴史総合 近代から現代へ || B5判
|-
| 708 || 山川出版社 || 現代の歴史総合 みる・読みとく・考える || AB判
|-
| 709 || 山川出版社 || わたしたちの歴史 日本から世界へ || AB判
|-
| 710 || 第一学習社 || 高等学校 歴史総合 || AB判
|-
| 711 || 第一学習社 || 高等学校 新歴史総合 過去との対話、つなぐ未来 || AB判
|-
| 712 || 明成社 || 私たちの歴史総合 || B5判
|}
===日本史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 日本史探究 || B5判
|-
| 702 || 実教出版 || 日本史探究 || B5判変型
|-
| 703 || 実教出版 ||精選日本史探究 今につなぐ 未来をえがく || AB判
|-
| 704 || 清水書院 || 高等学校 日本史探究 || B5判
|-
| 705 || 山川出版社 || 詳説日本史 || B5判変型
|-
| 706 || 山川出版社 || 高校日本史|| B5判
|-
| 707 || 第一学習社 || 高等学校 日本史探究 || B5判
|}
===世界史探究===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 世界史探究 || B5判
|-
| 702 || 実教出版 || 世界史探究 || B5判変型
|-
| 703 || 帝国書院 || 新詳世界史探究 || B5判
|-
| 704 || 山川出版社 || 詳説世界史 || B5判変型
|-
| 705 || 山川出版社 || 高校世界史 || B5判
|-
| 706 || 山川出版社 || 新世界史 || B5判変型
|-
| 707 || 第一学習社 || 高等学校 世界史探究 || B5判
|}
===地図===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新高等地図 || A4判
|-
| 702 || 帝国書院 || 新詳高等地図 || AB判
|-
| 703 || 帝国書院 || 標準高等地図 || A4判
|-
| 704 || 二宮書店 || 高等地図帳 || B5判
|-
| 705 || 二宮書店 || 詳解現代地図 最新版 || AB判
|-
| 706 || 二宮書店 || 基本地図帳 || A4判
|-
| 707 || 二宮書店 || コンパクト地理総合地図 || AB判変型
|}
==公民==
===公共===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||公共||AB判
|-
|702||教育図書||公共||B5判
|-
|703||実教出版||詳述公共||A5判
|-
|704||実教出版||公共||B5判
|-
|705||清水書院||高等学校 公共||B5判
|-
|706||清水書院||私たちの公共||AB判
|-
|707||帝国書院||高等学校 公共||AB判
|-
|708||数研出版||公共(令和4年度)||
|-
|709||数研出版||高等学校 公共 これからの社会について考える||AB判
|-
|710||第一学習社||高等学校 公共||B5判
|-
|711||第一学習社||高等学校 新公共||AB判
|-
|712||東京法令出版||公共||B5判
|-
|713||数研出版||新版 公共(令和5年度)||B5判
|}
===倫理===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 倫理 || B5判変型
|-
| 702 || 実教出版 || 詳述倫理 || A5判
|-
| 703 || 清水書院 || 高等学校 新倫理 || A5判
|-
| 704 || 数研出版 || 倫理 || A5判
|-
| 705 || 第一学習社 || 高等学校 倫理 || B5判
|}
===政治・経済===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
|701||東京書籍||政治・経済||B5判変型
|-
|702||実教出版||詳述政治・経済||A5判
|-
|703||実教出版||最新政治・経済||B5判
|-
|704||清水書院||高等学校 政治・経済||A5判
|-
|705||数研出版||政治・経済||A5判
|-
|706||第一学習社||高等学校 政治・経済||B5判
|}
==数学==
===数学Ⅰ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅰ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅰ Standard || A5判
|-
| 703 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学Ⅰ || B5判
|-
| 705 || 東京書籍 || 新数学Ⅰ 解答編 || B5判
|-
| 706 || 実教出版 || 数学Ⅰ Progress || A5判
|-
| 707 || 実教出版 || 新編数学Ⅰ || A5判
|-
| 708|| 実教出版 || 高校数学Ⅰ || B5判
|-
| 709 || 啓林館 || 数学Ⅰ || A5判
|-
| 710 || 啓林館 || 新編数学Ⅰ || A5判
|-
| 711 || 啓林館 || 深進数学Ⅰ || A5判
|-
| 712 || 数研出版 || 数学Ⅰ || A5判
|-
| 713 || 数研出版 || 高等学校 数学Ⅰ || A5判
|-
| 714 || 数研出版 || 新編 数学Ⅰ || A5判
|-
| 715 || 数研出版 || 最新 数学Ⅰ || A5判
|-
| 716 || 数研出版 || 新 高校の数学Ⅰ || B5判
|-
| 717 ||数研出版 || NEXT 数学Ⅰ || A5判
|-
| 718 || 第一学習社|| 新編数学Ⅰ || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Ⅰサポートブック || B5判変型版
|}
===数学Ⅱ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅱ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅱ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅱ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅱ || A5判
|-
| 705|| 実教出版 || 高校数学Ⅱ || B5判
|-
| 706 || 啓林館 || 数学Ⅱ || A5判
|-
| 707 || 啓林館 || 新編数学Ⅱ || A5判
|-
| 708 || 啓林館 || 深進数学Ⅱ || A5判
|-
| 709 || 数研出版 || 数学Ⅱ || A5判
|-
| 710 || 数研出版 || 高等学校 数学Ⅱ || A5判
|-
| 711 || 数研出版 || 新編 数学Ⅱ || A5判
|-
| 712 || 数研出版 || 最新 数学Ⅱ || A5判
|-
| 713 ||数研出版 || NEXT 数学Ⅱ || A5判
|-
| 714 || 第一学習社|| 新編数学Ⅱ || B5判変型版
|-
| 715 || 第一学習社 || 新編数学Ⅱサポートブック || B5判変型版
|-
| 716 || 東京書籍 || 数学Ⅰ Essence || B5判変型版
|-
| 717 || 東京書籍 || 新数学Ⅱ || B5判
|-
| 718 || 東京書籍 || 新数学Ⅱ 解答編 || B5判
|-
| 719 || 数研出版 || 新 高校の数学Ⅱ || B5判
|}
===数学Ⅲ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学Ⅲ Advanced || A5判
|-
| 702 || 東京書籍 || 数学Ⅲ Standard || A5判
|-
| 703 || 実教出版 || 数学Ⅲ Progress || A5判
|-
| 704 || 実教出版 || 新編数学Ⅲ || A5判
|-
| 705 || 啓林館 || 数学Ⅲ || A5判
|-
| 706 || 啓林館 || 新編数学Ⅲ || A5判
|-
| 707 || 啓林館 || 深進数学Ⅲ || A5判
|-
| 708 || 数研出版 || 数学Ⅲ || A5判
|-
| 709 || 数研出版 || 高等学校 数学Ⅲ || A5判
|-
| 710 || 数研出版 || 新編 数学Ⅲ || A5判
|-
| 711 || 数研出版 || 最新 数学Ⅲ || A5判
|-
| 712 ||数研出版 || NEXT 数学Ⅲ || A5判
|}
===数学A===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学A Advanced || A5判
|-
| 702 || 東京書籍 || 数学A Standard || A5判
|-
| 703 || 東京書籍 || 数学A Essence || B5判変型版
|-
| 704 || 東京書籍 || 新数学A || B5判
|-
| 705 || 東京書籍 || 新数学A 解答編 || B5判
|-
| 706 || 実教出版 || 数学A Progress || A5判
|-
| 707 || 実教出版 || 新編数学A || A5判
|-
| 708|| 実教出版 || 高校数学A || B5判
|-
| 709 || 啓林館 || 数学A || A5判
|-
| 710 || 啓林館 || 新編数学A || A5判
|-
| 711 || 啓林館 || 深進数学A || A5判
|-
| 712 || 数研出版 || 数学A || A5判
|-
| 713 || 数研出版 || 高等学校 数学A || A5判
|-
| 714 || 数研出版 || 新編 数学A || A5判
|-
| 715 || 数研出版 || 最新 数学A || A5判
|-
| 716 || 数研出版 || 新 高校の数学A || B5判
|-
| 717 ||数研出版 || NEXT 数学A || A5判
|-
| 718 || 第一学習社|| 新編数学A || B5判変型版
|-
| 719 || 第一学習社 || 新編数学Aサポートブック || B5判変型版
|}
===数学B===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学B Advanced || A5判
|-
| 702 || 東京書籍 || 数学B Standard || A5判
|-
| 703 || 東京書籍 || 数学B Essence || B5判変型版
|-
| 704 || 実教出版 || 数学B Progress || A5判
|-
| 705 || 実教出版 || 新編数学B || A5判
|-
| 706|| 実教出版 || 高校数学B || B5判
|-
| 707 || 啓林館 || 数学B || A5判
|-
| 708 || 啓林館 || 新編数学B || A5判
|-
| 709 || 啓林館 || 深進数学B || A5判
|-
| 710 || 数研出版 || 数学B || A5判
|-
| 711 || 数研出版 || 高等学校 数学B || A5判
|-
| 712 || 数研出版 || 新編 数学B || A5判
|-
| 713 || 数研出版 || 最新 数学B || A5判
|-
| 714 || 数研出版 || 新 高校の数学B || B5判
|-
| 715 ||数研出版 || NEXT 数学B || A5判
|-
| 716 || 第一学習社|| 新編数学B || B5判変型版
|}
===数学C===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 数学C Advanced || A5判
|-
| 702 || 東京書籍 || 数学C Standard || A5判
|-
| 703 || 実教出版 || 数学C Progress || A5判
|-
| 704 || 実教出版 || 新編数学C || A5判
|-
| 705 || 啓林館 || 数学C || A5判
|-
| 706 || 啓林館 || 新編数学C || A5判
|-
| 707 || 啓林館 || 深進数学C || A5判
|-
| 708 || 数研出版 || 数学C || A5判
|-
| 709 || 数研出版 || 高等学校 数学C || A5判
|-
| 710 || 数研出版 || 新編 数学C || A5判
|-
| 711 || 数研出版 || 最新 数学C || A5判
|-
| 712 || 数研出版 || NEXT 数学C || A5判
|-
| 713 || 第一学習社 || 新編数学C || B5判変型
|}
==理科==
===科学と人間生活===
{| class="wikitable sortable"
|-
!番号!!出版社!!教科書名!!判型
|-
| 701 || 東京書籍 || 科学と人間生活 || B5判変型
|-
| 702 || 実教出版 || 科学と人間生活 || B5判
|-
| 703 || 啓林館 || 高等学校 科学と人間生活 || B5判
|-
| 704 || 数研出版 || 科学と人間生活 || AB判
|-
| 705 || 第一学習社 || 高等学校 科学と人間生活 || B5判
|}
===物理基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|物理基礎
|B5判変型
|-
|702
|東京書籍
|新編物理基礎
|B5判
|-
|703
|実教出版
|物理基礎
|B5判
|-
|704
|実教出版
|高校物理基礎
|B5判
|-
|705
|啓林館
|高等学校 物理基礎
|A5判
|-
|706
|啓林館
|高等学校 考える物理基礎
|B5判
|-
|707
|数研出版
|物理基礎
|A5判
|-
|708
|数研出版
|新編 物理基礎
|B5判
|-
|709
|第一学習社
|高等学校 物理基礎
|B5判変型
|-
|710
|第一学習社
|高等学校 新物理基礎
|B5判
|}
===物理===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|物理
|B5判変型
|-
|702
|実教出版
|物理
|B5判
|-
|703
|啓林館
|高等学校 物理
|A5判
|-
|704
|啓林館
|高等学校 総合物理1 様々な運動 熱 波
|A5判
|-
|705
|啓林館
|高等学校 総合物理2 電気と磁気 原子・分子の世界
|A5判
|-
|706
|数研出版
|物理
|A5判
|-
|707
|数研出版
|総合物理1 力と運動・熱
|A5判
|-
|708
|数研出版
|総合物理2 波・電気と磁気・原子
|A5判
|-
|709
|第一学習社
|高等学校 物理
|B5判変型
|}
===化学基礎===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学基礎
|B5判変型
|-
|702
|東京書籍
|新編化学基礎
|B5判
|-
|703
|実教出版
|化学基礎 academia
|A5判
|-
|704
|実教出版
|化学基礎
|B5判
|-
|705
|実教出版
|高校化学基礎
|B5判
|-
|706
|啓林館
|高等学校 化学基礎
|A5判
|-
|707
|啓林館
|i版 化学基礎
|AB判
|-
|708
|数研出版
|化学基礎
|A5判
|-
|709
|数研出版
|高等学校 化学基礎
|B5判変型
|-
|710
|数研出版
|新編 化学基礎
|B5判
|-
|711
|第一学習社
|高等学校 化学基礎
|B5判変型
|-
|712
|第一学習社
|高等学校 化学基礎
|B5判
|}
===化学===
{| class="wikitable"
! 番号 !! 出版社
!教科書名
!判型
|-
| 701 || 東京書籍
|化学 Vol.1 理論編
|B5判変型
|-
|702
|東京書籍
|化学 Vol.2 物質編
|B5判変型
|-
|703
|実教出版
|化学 academia
|A5判
|-
|704
|実教出版
|化学
|B5判
|-
|705
|啓林館
|高等学校 化学
|A5判
|-
|706
|数研出版
|化学
|A5判
|-
|707
|数研出版
|新編 化学
|B5判
|-
|708
|第一学習社
|高等学校 化学
|B5判変型
|}
===生物基礎===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|生物基礎
|B5判変型
|-
|702
|東京書籍
|新編生物基礎
|B5判
|-
|703
|実教出版
|生物基礎
|B5判
|-
|704
|実教出版
|高校生物基礎
|B5判
|-
|705
|啓林館
|高等学校 生物基礎
|B5判変型
|-
|706
|啓林館
|i版 生物基礎
|AB判
|-
|707
|数研出版
|生物基礎
|A5判
|-
|708
|数研出版
|高等学校 生物基礎
|B5判変型
|-
|709
|数研出版
|新編 生物基礎
|B5判
|-
|710
|第一学習社
|高等学校 生物基礎
|B5判変型
|-
|711
|第一学習社
|高等学校 新生物基礎
|B5判
|}
===生物===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||生物||B5判変型
|-
|702||実教出版||生物||B5判
|-
|703||啓林館||高等学校 生物||B5判変型
|-
|704||数研出版||生物||B5判変型
|-
|705||第一学習社||高等学校 生物||B5判変型
|}
===地学基礎===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||東京書籍||地学基礎||B5判
|-
|702||実教出版||地学基礎||B5判
|-
|703||啓林館||高等学校 地学基礎||B5判変型
|-
|704||数研出版||高等学校 地学基礎||B5判変型
|-
|705||第一学習社||高等学校 地学基礎||B5判
|}
===地学===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||啓林館||高等学校 地学||A5判
|}
== 保健体育 ==
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||大修館書店||現代高等保健育||B5判
|-
|702||大修館書店||新高等保健体育||B5判変型
|-
|703||第一学習社||高等学校 保健体育 Textbook||B5判
|-
|704||第一学習社||高等学校 保健体育 Activity||B5判
|}
== 芸術 ==
=== 音楽Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅰ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽1 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA1 || A4判
|-
| 704 || 音楽之友社 || ON! 1 || A4判変型
|}
=== 音楽Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 教育出版 || 音楽Ⅱ Tutti+ || A4判
|-
| 702 || 教育芸術社 || 高校生の音楽2 || A4判変型
|-
| 703 || 教育芸術社 || MOUSA2 || A4判
|-
| 704 || 音楽之友社 || ON! 2 || A4判変型
|}
=== 美術Ⅰ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 ||美術1 || A4判変型
|-
| 702 ||日本文教出版 ||高校生の美術1 ||A4判
|-
| 703 || 日本文教出版 ||高校美術 ||A4判変型
|}
=== 美術Ⅱ ===
{| class="wikitable sortable"
|-
!番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 光村図書出版 || 美術2 ||A4判変型
|-
| 702 || 日本文教出版 || 高校生の美術2 ||A4判
|}
=== 工芸Ⅰ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅰ||A4判
|}
=== 工芸Ⅱ ===
{| class="sortable wikitable"
|-
! 番号 !! 出版社 !!教科書名!!判型
|-
|701||日本文教出版||工芸Ⅱ||A4判
|}
=== 書道Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅰ || A4判
|-
| 702 || 教育図書 || 書Ⅰ || A4判
|-
| 703 || 教育図書 || 書Ⅰプライマリーブック || A4判
|-
| 704 || 教育出版 || 書道Ⅰ || A4判
|-
| 705 || 光村図書出版 || 書Ⅰ || A4判
|}
=== 書道Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 書道Ⅱ || A4判
|-
| 702 || 教育図書 || 書Ⅱ || A4判
|-
| 703 || 教育出版 || 書道Ⅱ || A4判
|-
| 704 || 光村図書出版 || 書Ⅱ || A4判
|}
== 外国語 ==
=== 英語コミュニケーションⅠ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅰ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅠ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅠ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅠ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅠ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅠ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅠ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅠ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅠ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅰ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅰ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅰ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅰ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅰ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅰ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅰ
|AB判
|-
|719
|文英堂
|Grove English CommunicationⅠ
|B5判
|-
|720
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅰ
|B5判
|-
|721
|第一学習社
|CREATIVE English Communication Ⅰ
|B5判
|-
|722
|第一学習社
|Vivid English Communication Ⅰ
|B5判
|-
|723
|桐原書店
|Heartening English Communication Ⅰ
|B5判
|-
|724
|いいずな書店
|New Rays English Communication Ⅰ
|B5判変型
|-
|725
|Cambridge University Press & Assessment
|Cambridge Experience 1
|A4判
|}
=== 英語コミュニケーションⅡ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|All Aboard! English Communication Ⅱ
|B5判
|-
|702
|東京書籍
|Power On English CommunicationⅡ
|B5判
|-
|703
|東京書籍
|ENRICH LEARNING ENGLISH COMMUNICATIONⅡ
|AB判
|-
|704
|開隆堂
|Amity English CommunicationⅡ
|B5判
|-
|705
|開隆堂
|APPLAUSE ENGLISH COMMUNICATIONⅡ
|B5判
|-
|706
|開隆堂
|Ambition English CommunicationⅡ
|B5判
|-
|707
|三省堂
|CROWN English CommunicationⅡ
|B5判
|-
|708
|三省堂
|MY WAY English CommunicationⅡ
|B5判
|-
|709
|三省堂
|VISTA English CommunicationⅡ
|B5判
|-
|710
|大修館書店
|Crossroads English Communication Ⅱ
|B5判
|-
|711
|大修館書店
|PANORAMA English Communication 1
|B5判
|-
|712
|啓林館
|ELEMENT English Communication Ⅱ
|B5判
|-
|713
|啓林館
|LANDMARK English Communication Ⅱ
|B5判変型
|-
|714
|啓林館
|LANDMARK Fit English Communication Ⅱ
|B5判変型
|-
|715
|数研出版
|BLUE MARBLE English Communication Ⅱ
|B5判
|-
|716
|数研出版
|BIG DIPPER English Communication Ⅱ
|B5判
|-
|717
|数研出版
|COMET English Communication Ⅱ
|AB判
|-
|718
|文英堂
|Grove English CommunicationⅡ
|B5判
|-
|719
|増進堂
|FLEX ENGLISH COMMUNICATION Ⅱ
|B5判
|-
|720
|第一学習社
|CREATIVE English Communication Ⅱ
|B5判
|-
|721
|第一学習社
|Vivid English Communication Ⅱ
|B5判
|-
|722
|桐原書店
|Heartening English Communication Ⅱ
|B5判
|-
|723
|いいずな書店
|New Rays English Communication Ⅱ
|B5判変型
|-
|724
|Cambridge University Press & Assessment
|Cambridge Experience 2
|A4判
|}
=== 論理・表現Ⅰ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|NEW FAVORITE English Logic and Expression Ⅰ
|B5判
|-
|702
|開隆堂
|Amity English Logic and Expression Ⅰ
|A4判
|-
|703
|開隆堂
|APPLAUSE ENGLISH LOGIC AND EXPRESSION Ⅰ
|B5判
|-
|704
|三省堂
|CROWN Logic and ExpressionⅠ
|B5判
|-
|705
|三省堂
|MY WAY Logic and ExpressionⅠ
|B5判
|-
|706
|三省堂
|VISTA Logic and ExpressionⅠ
|B5判
|-
|707
|大修館書店
|Genius English Logic and Expression Ⅰ
|B5判
|-
|708
|啓林館
|Vision Quest English Logic and Expression Ⅰ Advanced
|B5判
|-
|709
|啓林館
|Vision Quest English Logic and Expression Ⅰ Standard
|B5判
|-
|710
|数研出版
|EARTHRISE English Logic and Expression Ⅰ Advanced
|B5判
|-
|711
|数研出版
|EARTHRISE English Logic and Expression Ⅰ Standard
|B5判
|-
|712
|数研出版
|BIG DIPPER English Logic and Expression Ⅰ
|B5判
|-
|713
|増進堂
|MAINSTREAM English Logic and Expression Ⅰ
|B5判
|-
|714
|桐原書店
|FACTBOOK English Logic and Expression Ⅰ
|B5判
|-
|715
|CHEERS
|ATLANTIS Logic and ExpressionⅠStandard
|B5判
|-
|716
|いいずな書店
|Harmony English Logic and Expression Ⅰ
|AB判
|-
|717
|いいずな書店
|be English Logic and Expression Ⅰ Clear
|B5判
|-
|718
|いいずな書店
|be English Logic and Expression Ⅰ Smart
|B5判
|}
=== 論理・表現Ⅱ ===
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|東京書籍
|NEW FAVORITE English Logic and Expression Ⅱ
|B5判
|-
|702
|開隆堂
|Amity English Logic and Expression Ⅱ
|A4判
|-
|703
|開隆堂
|APPLAUSE ENGLISH LOGIC AND EXPRESSION Ⅱ
|B5判
|-
|704
|三省堂
|CROWN Logic and ExpressionⅡ
|B5判
|-
|705
|三省堂
|MY WAY Logic and ExpressionⅡ
|B5判
|-
|706
|三省堂
|VISTA Logic and ExpressionⅡ
|B5判
|-
|707
|大修館書店
|Genius English Logic and Expression Ⅱ
|B5判
|-
|708
|啓林館
|Vision Quest English Logic and Expression Ⅱ Advanced
|B5判
|-
|709
|啓林館
|Vision Quest English Logic and Expression Ⅱ Standard
|B5判
|-
|710
|数研出版
|EARTHRISE English Logic and Expression Ⅱ Advanced
|B5判
|-
|711
|数研出版
|EARTHRISE English Logic and Expression Ⅱ Standard
|B5判
|-
|712
|数研出版
|BIG DIPPER English Logic and Expression Ⅱ
|B5判
|-
|713
|増進堂
|MAINSTREAM English Logic and Expression Ⅱ
|B5判
|-
|714
|桐原書店
|FACTBOOK English Logic and Expression Ⅱ
|B5判
|-
|715
|いいずな書店
|Harmony English Logic and Expression Ⅱ
|AB判
|-
|716
|いいずな書店
|be English Logic and Expression Ⅱ Clear
|B5判
|-
|717
|いいずな書店
|be English Logic and Expression Ⅱ Smart
|B5判
|}
== 家庭 ==
=== 家庭基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭基礎 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭基礎365 || AB判
|-
| 703 || 教育図書 || 家庭基礎 つながる暮らし 共に創る未来 || B5判
|-
| 704 || 教育図書 || Survive!! 高等学校 家庭基礎 || AB判
|-
| 705 || 実教出版 || 家庭基礎 気づく力 築く未来 || AB判
|-
| 706 || 実教出版 || Agenda家庭基礎 || B5判
|-
| 707 || 実教出版 || 図説家庭基礎 || AB判
|-
| 708 || 開隆堂 || 家庭基礎 明日の生活を築く || AB判
|-
| 709 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭基礎』で生活をつくろう || A4判
|-
| 710 || 第一学習社 || 高等学校 家庭基礎 持続可能な未来をつくる || AB判
|}
=== 家庭総合 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 家庭総合 自立・共生・創造 || AB判
|-
| 702 || 教育図書 || 未来へつなぐ 家庭総合365 || AB判
|-
| 703 || 実教出版 || 家庭総合 || AB判
|-
| 704 || 開隆堂 || 家庭総合 明日の生活を築く || AB判
|-
| 705 || 大修館書店 || クリエイティブ・リビングCreative Living『家庭総合』で生活をつくろう || A4判
|-
| 706 || 第一学習社 || 高等学校 家庭総合 持続可能な未来をつくる || AB判
|}
== 情報 ==
=== 情報Ⅰ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 新編情報Ⅰ || B5判
|-
| 702 || 東京書籍 || 情報Ⅰ Step Forward! || B5判
|-
| 703 || 実教出版 || 高校情報Ⅰ Python || B5判
|-
| 704 || 実教出版 || 高校情報Ⅰ JavaScript || B5判
|-
| 705 || 実教出版 || 最新情報Ⅰ || B5判
|-
| 706 || 実教出版 || 図説情報Ⅰ || AB判
|-
| 707 || 開隆堂 || 実践 情報Ⅰ || B5判
|-
| 708 || 数研出版 || 高等学校 情報Ⅰ || B5判
|-
| 709 || 数研出版 || 情報Ⅰ Next || B5判
|-
| 710 || 日本文教出版 || 情報Ⅰ || B5判変型
|-
| 711 || 日本文教出版 || 情報Ⅰ図解と実習-図解編 || B5判変型
|-
| 712 || 日本文教出版 || 情報Ⅰ図解と実習-実習編 || B5判変型
|-
| 713 || 第一学習社 || 高等学校 情報Ⅰ || AB判
|}
=== 情報Ⅱ ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 東京書籍 || 情報Ⅱ || B5判
|-
| 702 || 実教出版 || 情報Ⅱ || B5判
|-
| 703 || 日本文教出版 || 情報Ⅱ || B5判変型
|}
== 理数 ==
=== 理数探究基礎 ===
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 啓林館 || 理数探究基礎 未来に向かって || A4判
|-
| 702 || 数研出版 || 理数探究基礎 || B5判
|}
== 農業 ==
{| class="wikitable sortable"
!番号
!出版社
!教科書名
!判型
|-
|701
|実教出版
|農業と環境
|B5判
|-
|702
|実教出版
|農業と情報
|B5判
|-
|708
|実教出版
|草花
|B5判
|-
|710
|実教出版
|栽培と環境
|B5判
|-
|709
|実教出版
|農業機械
|B5判
|-
|703
|実教出版
|植物バイオテクノロジー
|B5判
|-
|704
|実教出版
|食品製造
|B5判
|-
|711
|実教出版
|生物活用
|B5判
|-
|705
|実教出版
|森林科学
|B5判
|-
|712
|実教出版
|森林経営
|
|-
|706
|実教出版
|農業土木設計
|B5判
|-
|713
|東京電機大学
|農業土木施工
|B5判
|-
|707
|実教出版
|造園計画
|B5判
|-
|714
|東京電機大学
|造園施工管理
|B5判
|}
== 工業 ==
== 商業 ==
== 水産 ==
== 家庭 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || ファッションデザイン || B5判
|-
| 702 || 教育図書 || フードデザイン Food Changes LIFE || AB判
|-
| 703 || 実教出版 || フードデザイン || AB判
|-
| 704 || 実教出版 || 生活産業情報 || B5判
|-
| 705 || 実教出版 || ファッション造形基礎 || B5判
|-
| 706 || 教育図書 || 保育基礎 ようこそ、ともに育ち合う保育の世界へ || AB判
|-
| 707 || 実教出版 || 保育基礎 || B5判
|-
| 708 || 実教出版 || 消費生活 || B5判
|-
| 709 || 実教出版 || 保育実践 || B5判
|-
| 710 || 実教出版 || 服飾文化 || B5判
|}
== 看護 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 基礎看護 || B5判
|}
== 情報 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 情報産業と社会 || B5判
|-
| 702 || 実教出版 || 情報の表現と管理 || B5判
|-
| 703 || 東京電機大学 || 情報システムのプログラミング || B5判
|-
| 704 || 実教出版 || 情報セキュリティ || B5判
|-
| 705 || 実教出版 || 情報デザイン || B5判
|-
| 706 || 実教出版 || ネットワークシステム || B5判
|-
| 707 || 実教出版 || データベース || B5判
|}
== 福祉 ==
{| class="wikitable sortable"
|-
! 番号 !! 出版社 !! 教科書名 !! 判型
|-
| 701 || 実教出版 || 社会福祉基礎 || B5判
|-
| 702 || 実教出版 || 介護福祉基礎 || B5判
|-
| 703 || 実教出版 || 生活支援技術 || B5判
|-
| 704 || 実教出版 || こころとからだの理解 || B5判
|}
==脚注==
*[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
mqpczvrhfono6b4gg1gg9lmx9hecpfk
検定教科書
0
28820
205821
205192
2022-07-25T06:16:39Z
Kwawe
68789
/* 2023年度発行者リスト */
wikitext
text/x-wiki
{{Pathnav|メインページ|小学校・中学校・高等学校の学習|frame=1}}
'''検定教科書'''(けんていきょうかしょ)とは、小学校・中学校・高等学校で使用している教科書のことを指します。この項目では、検定教科書の役割・閲覧入手方法・教科書番号について解説します。
==はじめに==
[[File:日本の教科書.jpg|thumb|検定済教科書の表示が書かれた教科書]]
[[File:Image of MEXT certified textbook.svg|thumb|220px|教科書(番号)のイメージ ※内容は架空のもの]]
小学校・中学校・高等学校で使用されている教科書は、文部科学省大臣の検定を受けた上で出版されています。この検定を受けて正式に教科書として利用できる教科書のことを、'''文部科学省検定済教科書'''(以下、「検定教科書」あるいは単に「教科書」)といいます。なお、特別支援学校の教科書の一部や高等学校の専門科目の一部は文部科学省が著作しており、'''文部科学省著作教科書'''と呼ばれます。検定教科書は4年のサイクルで検定・採択が行われます。検定教科書は4~5年ごとに改訂されます<ref>毎年、「改訂」ほどでなくとも、誤字の修正・情報の更新などを行うことがあります。</ref>。公立学校では市区町村ごとに、国立・私立学校では学校ごとに採択教科書を決定します。
各教科書には、'''教科書番号'''が付与されています。この教科書番号で、特定の教科書を把握したり、市販のワークブックを購入したりする際の参考となります。
== 検定教科書の閲覧入手方法 ==
小中高校で教育を受ける場合は、入手できる手段が確保出来ています<ref>小中学校の検定教科書は、税金を利用して無償で賄われています。</ref>。研究目的の編集者の場合は、検定教科書は一般の書店では売っていないので、もし小学生・中学生・高校生の家族がいるなら、使い終わった検定教科書を捨てさせずに、譲ってもらうという方法もあります(古い場合があるので注意しましょう)。
以下、検定教科書の購入方法および検定教科書を閲覧する方法を紹介します。
=== 検定教科書購入方法 ===
この節では、上記の入手法とは別に、自分で検定教科書を購入する場合について述べます(このような購入も法的に出来ます)。学校で児童・生徒に配布される教科書は、税金を通して無償で賄われていますが、一般販売の教科書を購入する場合は有償となります。
* 各学校の教科書取次店や教科書取扱店で注文出来るのが普通です。全ての都道府県にその都道府県の学校の教科書(場合によってはほかの教科書も)を取り扱っている教科書取次店や教科書取扱店があります。
* ただし、一般の書店では原則として検定教科書は取り扱っていないので注意しましょう。
例えば東京圏であれば、神保町三省堂書店や、または第一教科書<ref>JR中央線大久保駅南口にある。東京都新宿区百人町1丁目22-20</ref>などで購入や注文が行えます。
{{コラム|教科書の価格|定価については[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm こちら]に記載されている値段と同じである。小学校・中学校の各教科で出版社に関係なく価格が固定されており、1つの教科書の値段が最も安いもので1冊約150円 <!-- 小学校書写 -->、最も高いもので1冊約1,350円<!-- 高校地図 ※専門分野の教科書は対象外とした場合-->までさまざまである。なお1つの教科書が複数冊になっている場合(上巻と下巻、教科書と教科書準拠ノートなど)は、それぞれの価格の合計が決まった価格となっている。|}}
{{コラム|教科書の購入時期|教科書は、普通3月~4月上旬、あるいは8月~9月上旬に学校に配布される。当然児童・生徒への配布が最優先であるため、一般向けへの配布はやや遅れる。規定により、小中学校の1冊で構成されている教科書や2冊制の教科書の上巻(前期通年用)は4月16日から、2冊制の教科書の下巻(後期用)は9月16日より販売となる。}}
{{コラム|2020年度の小学校教科書の使用|小学校4年の社会は、2019年度に3年の教科書とともに配布された教科書を使うため2020年は発行されない。また、学習指導要領での記述が2学年ごとになっているが、教科書は学年ごとに発行される国語・書写・生活・音楽・道徳において、偶数学年については、旧教科書を使用することも可能である。}}
=== 検定教科書の閲覧方法 ===
教科書を購入せずに閲覧したい場合、あるいは過去に出版された教科書を閲覧したい場合の方法を紹介します。
まず、その地域の図書館を利用してみましょう。市区町村の図書館には、その市区町村立小・中学校で使用している教科書(およびほかの教科書)を置いていることがあります。地域により異なりますが、借りることが出来る場合があるので、興味があるなら図書館に行ってみるとよいでしょう。
また、[[w:国立国会図書館]]([[w:国際子ども図書館]])を利用する方法があります。国会図書館に行けば、余程のことがない限り全ての教科書を閲覧することが出来ます。探している教科書がどうしてもない場合は、活用してみると良いでしょう。
さらに、教科書採択を実施する年には、6月12日~7月31日までの任意の14日間ほど、各都道府県の施設で住民に採択する教科書についての意見を聞くための教科書展示会が行われるため<ref>実施機関や教科書の種類などは都道府県によって異なるので、各都道府県のホームページなどを参考にしてください。</ref>、教科書の見本を閲覧することが出来ます。ただし、本来の目的は住民に意見を問うことであるため、できれば閲覧した後に意見などを書いておきましょう。
なお、各教科書会社のホームページにアクセスすると教員向けの「年間指導計画」を見ることが出来ます(教員でなくても見られる場合がほとんどです)から、それを閲覧することで大まかな内容を知ることが出来ます。
==特殊な教科書==
=== 小・中学の副読本 ===
小学校・中学校の、学校で配られるような、教科書準拠の資料集やワークブック類などの副読本の多くは、原則的として一般人は購入できない<ref>書店に並んでいるワークブック類は、学校配布ワークブックとは別のワークブックの場合が多い。</ref>。これら学校配布の副読本は、行政的に流通が規制されていたり、または出版元・販売元である学校配布教材の教材会社が、教科書取扱店での市販に消極的であったりする。なので、もし私たち一般人が教科書取扱店で注文しても、その地域の小学校・中学校の教員による許可がないと中間業者が注文を受け付けず、担当科目の教員でない一般人は購入できないのが通常である。
ところで、もし研究目的の編集者で教材を購入する場合、いくつかの教科では検定教科書だけではなく副読本などの別教材も確認する必要がある。
また、一見すると検定教科書に見えても、分類上は検定教科書でない教材もある。例えば、体育実技のための学校配布の書籍(いろんなスポーツのルールや練習例の写真・イラストのある本)は、教科書会社発行の副読本である。保健体育の検定教科書では、保健分野と体育理論のみとなる<ref>規定により、体育実技は取り上げてはいけないことになっているため。</ref>。
=== 中高一貫校での教科書 ===
中高一貫校(おもに中学部)などでは検定教科書を配布のみ行い使用せず、「中高一貫校専用の教科書」を用いる場合がある(検定教科書ではない)。代表的なものに、「体系数学」「NEW TRESURE」「PROGRESS IN ENGLISH」などがある。このようなものは、やや規模の大きな書店などで購入できる(実際に学校で使用されているものと比較するとデザインがわずかに異なる場合がある。また、学校独自の教科書である場合もあるので注意すること)。なお、学校独自の教科書を用いている場合もあり、それに関してはほとんど購入不可能である。
== 教科書番号 ==
[[w:教科書番号|教科書番号]]とは、文部科学省が小中学校・高等学校の検定教科書に割り振っている番号のことです。出版社名(略称)と発行者の番号<ref name="hako-no">ISBNの出版社記号とは別物である。また、1番から233番のすべてに対応している教科書会社があるが、「すでに教科書事業から撤退したもの(廃業したもの)」、「現在採択されていないもの」、「特別支援学校の教科書のみを作成しているもの」については記載していない。</ref>・教科/科目名と3ケタの数字で構成されています。
各検定教科書については[[/小中学校|小中学校の教科書について]]、[[/高等学校|高等学校の教科書について]]をご覧ください。
=== 2023年度発行者リスト ===
(現在、新課程版に改定作業中です。改訂作業をお手伝いいただける方はご協力ください。)
以下、出版社名にあるリンクは、その出版社の公式ホームページ(の教科書ページ)のものです。連絡先やなどは、当該ぺージを参考にしてください。
<!-- 発行者名は「教科書表紙に記載のもの」と統一しています -->
{| class="wikitable sortable"
|-
! 発行者<br>番号<ref name="hako-no"/>!! 発行者<br>略称 !! 出版社名
! style="width:18em"|発行教科書(小学校)
! style="width:18em"|発行教科書(中学校)
! style="width:18em"|発行教科書(高等学校)
|-
|2||東書||[https://www.tokyo-shoseki.co.jp/ 東京書籍]|| 国語・書写・社会・地図・算数・理科・生活・家庭・保健体育・英語・道徳 || 国語・書写・社会(地理・歴史・公民)・地図・数学・理科・保健体育・技術・家庭・英語・道徳 || 国語・地歴(世界史・日本史・地理)・地図・公民(政治経済・倫理・公共)・地図・数学・理科・芸術(書道)・英語(コミュニケーション・表現・会話)・家庭(一般教科)・情報(社会・科学)
|-
|4||大日本||[https://www.dainippon-tosho.co.jp/ 大日本図書]|| 算数・理科・生活・保健体育 || 数学・理科・保健体育
|style="background-color:#777" |(なし)
|-
|6||教図||[https://www.kyoiku-tosho.co.jp/index_top.php 教育図書]
|style="background-color:#777" |(なし) || 技術・家庭 ||芸術(書道)・家庭(一般教科)・家庭(専門教科)・公民(公共)
|-
|7||実教||[http://www.jikkyo.co.jp/ 実教出版]
|style="background-color:#777" |(なし)
|style="background-color:#777"|(なし) || 地歴(世界史・日本史)・公民(公共・政治経済・倫理)・数学・理科・家庭(一般教科)・情報(社会・科学)・農業・工業・商業・水産・家庭(専門教科)・福祉
|-
|9|| 開隆堂 ||[https://www.kairyudo.co.jp/ 開隆堂]|| 図画工作・家庭・英語 || 美術・技術・家庭・英語 || 英語・家庭(一般教科)・情報(社会)
|-
|11|| 学図 ||[https://gakuto.co.jp/ 学校図書]|| 国語・書写・算数・理科・生活・英語・道徳 || 国語・書写・数学・理科・英語・道徳
|style="background-color:#777" |(なし)
|-
|15|| 三省堂 ||[https://tb.sanseido-publ.co.jp/e-school/ 三省堂]|| 英語 || 国語・書写・英語 || 国語・英語(コミュニケーション・表現・会話)
|-
|17|| 教出 ||[https://www.kyoiku-shuppan.co.jp/ 教育出版]|| 国語・書写・社会・算数・理科・生活・音楽・英語・道徳 || 国語・書写・社会(地理・歴史・公民)・数学・理科・英語・音楽(音楽・器楽)・道徳 ||芸術(音楽・書道)
|-
|26|| 信教 ||[http://www.shinkyo-pub.or.jp/ 信州教育出版社]|| 理科・生活
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)
|-
|27|| 教芸 ||[https://www.kyogei.co.jp/ 教育芸術社]|| 音楽 || 音楽(音楽・器楽) || 音楽
|-
|35|| 清水 ||[http://www.shimizushoin.co.jp/ 清水書院]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)<ref name="-2021">中学生の教科書は2021年で出版を終了した。</ref>
| 歴史(日本史探究・歴史総合)・公民(公共・政治・倫理)
|-
|38|| 光村 ||[https://www.mitsumura-tosho.co.jp/ 光村図書]|| 国語・書写・生活・英語・道徳 || 国語・書写・美術・英語・道徳 || 芸術(書道・美術)
|-
|46|| 帝国 ||[https://www.teikokushoin.co.jp/ 帝国書院]|| 地図 || 社会(地理・歴史・公民)・地図 || 地歴(地理総合・地理探究・歴史総合・世界史探究)・公民(公共)・地図
|-
|50|| 大修館 ||[https://www.taishukan.co.jp/kyokasho/ 大修館書店]
|style="background-color:#777" |(なし)|| 保健体育 || 国語・保健体育・英語(コミュニケーション・表現)・家庭
|-
|61|| 啓林館 ||[https://www.shinko-keirin.co.jp/keirinkan/index.html 啓林館]|| 算数・理科・生活・英語 || 数学・理科・英語 || 数学・理科・英語(コミュニケーション・表現・会話)
|-
|81|| 山川 ||[https://www.yamakawa.co.jp/ 山川出版社]
|style="background-color:#777" |(なし)
||社会(歴史)||地歴(歴史総合・世界史探究・日本史探究)
|-
|89|| 友社 ||[https://www.ongakunotomo.co.jp/ 音楽之友社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)|| 芸術(音楽)
|-
|104|| 数研 ||[https://www.chart.co.jp/ 数研出版]
|style="background-color:#777" |(なし)|| 数学 || 国語・公民(公共・倫理・政治・経済)・数学・理科・英語(コミュニケーション・表現)・情報(社会・科学)
|-
|109|| 文英堂 ||[https://www.bun-eido.co.jp/products/?menu=5&submenu=128 文英堂]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)|| 国語・英語(コミュニケーション・表現・会話)
|-
|116|| 日文 ||[https://www.nichibun-g.co.jp/ 日本文教出版]|| 書写・社会・算数・生活・図画工作・道徳 || 社会(地理・歴史・公民)・数学・美術・道徳 || 芸術(美術・工芸)・情報(社会・科学)
|-
|117|| 明治 ||[https://www.meijishoin.co.jp/ 明治書院]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語
|-
|130|| 二宮 ||[http://www.ninomiyashoten.co.jp/ 二宮書店]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 地理・地図
|-
|143|| 筑摩 ||[http://www.chikumashobo.co.jp/ 筑摩書房]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語
|-
|144|| 暁 ||[https://www.akatsuki-shuppan.co.jp/ 暁出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 商業
|-
|154|| オーム ||[https://www.ohmsha.co.jp/tbc/ オーム社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 工業
|-
|174|| コロナ ||[https://www.coronasha.co.jp/ コロナ社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 工業
|-
|177|| 増進堂 ||[https://www.zoshindo.co.jp/ 増進堂(受験研究社)]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(コミュニケーション・表現)
|-
|178|| 農文協 ||[http://www.ruralnet.or.jp/ 農山漁村文化協会]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 農業
|-
|179|| 電機大 ||[https://www.tdupress.jp/ 東京電機大学]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 農業・水産・工業
|-
|183|| 第一 ||[http://www.daiichi-g.co.jp/ 第一学習社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語・地歴(歴史総合・探究・地理総合)・公民・数学・理科・英語・家庭(一般教科)・保健体育・情報(社会・科学)
|-
|190|| 東法 ||[https://toho.tokyo-horei.co.jp/ 東京法令出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 商業・公民(公共)
|-
|201|| 海文堂 ||[http://www.kaibundo.jp/ 海文堂出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 農業・水産
|-
|205|| 三友 ||[http://sanyusha-shuppan.com/forteacher/textbook/ 三友社出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(コミュニケーション・表現)
|-
|207|| 文教 ||[http://www.bunkyosya.co.jp/ 文教社] || 保健体育
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)
|-
|208|| 光書 ||[https://www.kobun.co.jp/textbook/ 光文書院] || 保健体育・道徳
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)
|-
|212|| 桐原 ||[https://www.kirihara.co.jp/ 桐原書店]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語・英語(コミュニケーション・表現)
|-
|218|| 京書 ||[https://www.kyo-sho.com/ 京都書房]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語
|-
|220|| スクリ ||[https://www.screenplay.jp/text スクリーンプレイ]<ref>現・株式会社フォーインスクリーンプレイ</ref><ref name="-2020">2020年で出版を終了する。</ref>
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(表現)
|-
|221|| 明成 ||[https://meiseisha.com/%e6%95%99%e7%a7%91%e6%9b%b8-2/ 明成社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 地歴(日本史)
|-
|224|| 学研 ||[https://gakkokyoiku.gakken.co.jp/ 学研教育みらい]|| 保健体育・道徳 || 保健体育・道徳
|style="background-color:#777" |(なし)
|-
|225|| 自由社 ||[http://www.jiyuusha.jp/newpage28..html 自由社]
|style="background-color:#777" |(なし) || 社会(歴史・公民)
|style="background-color:#777" |(なし)
|-
|226|| チアーズ ||[https://atlantisenglish.com/ CHEERS]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(コミュニケーション・表現・会話)
|-
|227|| 育鵬社 ||[http://www.ikuhosha.co.jp/ 育鵬社]
|style="background-color:#777" |(なし) || 社会(歴史・公民)
|style="background-color:#777" |(なし)
|-
|228|| 山下 ||山下 明 <ref>個人出版である。[https://www.osaka-cu.ac.jp/ja/news/2012/a4yqqo 参考サイト]</ref><ref name="-2020"></ref>
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 工学
|-
|229|| 学び舎 ||[http://manabisha.com/ 学び舎]
|style="background-color:#777" |(なし) || 社会(歴史)
|style="background-color:#777" |(なし)
|-
|230|| ネット ||[https://book.net-school.co.jp/zensho/ ネットスクール]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 商業
|-
|231|| いいずな ||[https://www.iizuna-shoten.com/ いいずな書店]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(表現・英語コミュニケーション)
|-
|232|| 廣あかつき ||[https://www.kosaidoakatsuki.jp/ 廣済堂あかつき]|| 道徳 || 道徳
|style="background-color:#777" |(なし)
|-
|233|| 日科 ||[http://www.nihon-kyokasho.co.jp/ 日本教科書]
|style="background-color:#777" |(なし)|| 道徳
|style="background-color:#777" |(なし)
|-
|234
|TAC
|[https://shuppan.tac-school.co.jp/koukou/ TAC出版]
|
|
|商業
|-
|235
|CUP
|
|
|
|英語(英語コニュニケーション)
|-
|}
==脚注==
<references/>
==参考・関連項目==
* [[小学校・中学校・高等学校の学習]]
* [https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
* [https://www.aomoritosyo.co.jp/kyoukasho/tokuyaku/ 全国教科書取扱特約店一覧(青森県図書教育用品)] 全国の教科書販売店の一覧
* [http://www.daiichikyokasho.co.jp/ 第一教科書] 教科書・問題集直売店「第一教科書」
*[https://www.hirokyou.co.jp/ 広島教販] 教科書ネット通販「広島県教科用図書販売株式会社(広島教販)」
* [https://www.mext.go.jp/a_menu/shotou/kyoukasho/tenji/1359114.htm 2022年教科書展示会について(文部科学省)] - 現在は全都道府県で終了しています。
* [http://www.text-kyoukyuu.or.jp/ 社団法人 全国教科書供給協会] 教科書の価格、教科書発行者一覧など教科書に関する情報を載せる
{{DEFAULTSORT:けんていきようかしよ}}
[[Category:普通教育]]
qo3qx8mdwhu34u0w26tv6a12b7wogfo
205822
205821
2022-07-25T06:17:59Z
Kwawe
68789
/* 2023年度発行者リスト */
wikitext
text/x-wiki
{{Pathnav|メインページ|小学校・中学校・高等学校の学習|frame=1}}
'''検定教科書'''(けんていきょうかしょ)とは、小学校・中学校・高等学校で使用している教科書のことを指します。この項目では、検定教科書の役割・閲覧入手方法・教科書番号について解説します。
==はじめに==
[[File:日本の教科書.jpg|thumb|検定済教科書の表示が書かれた教科書]]
[[File:Image of MEXT certified textbook.svg|thumb|220px|教科書(番号)のイメージ ※内容は架空のもの]]
小学校・中学校・高等学校で使用されている教科書は、文部科学省大臣の検定を受けた上で出版されています。この検定を受けて正式に教科書として利用できる教科書のことを、'''文部科学省検定済教科書'''(以下、「検定教科書」あるいは単に「教科書」)といいます。なお、特別支援学校の教科書の一部や高等学校の専門科目の一部は文部科学省が著作しており、'''文部科学省著作教科書'''と呼ばれます。検定教科書は4年のサイクルで検定・採択が行われます。検定教科書は4~5年ごとに改訂されます<ref>毎年、「改訂」ほどでなくとも、誤字の修正・情報の更新などを行うことがあります。</ref>。公立学校では市区町村ごとに、国立・私立学校では学校ごとに採択教科書を決定します。
各教科書には、'''教科書番号'''が付与されています。この教科書番号で、特定の教科書を把握したり、市販のワークブックを購入したりする際の参考となります。
== 検定教科書の閲覧入手方法 ==
小中高校で教育を受ける場合は、入手できる手段が確保出来ています<ref>小中学校の検定教科書は、税金を利用して無償で賄われています。</ref>。研究目的の編集者の場合は、検定教科書は一般の書店では売っていないので、もし小学生・中学生・高校生の家族がいるなら、使い終わった検定教科書を捨てさせずに、譲ってもらうという方法もあります(古い場合があるので注意しましょう)。
以下、検定教科書の購入方法および検定教科書を閲覧する方法を紹介します。
=== 検定教科書購入方法 ===
この節では、上記の入手法とは別に、自分で検定教科書を購入する場合について述べます(このような購入も法的に出来ます)。学校で児童・生徒に配布される教科書は、税金を通して無償で賄われていますが、一般販売の教科書を購入する場合は有償となります。
* 各学校の教科書取次店や教科書取扱店で注文出来るのが普通です。全ての都道府県にその都道府県の学校の教科書(場合によってはほかの教科書も)を取り扱っている教科書取次店や教科書取扱店があります。
* ただし、一般の書店では原則として検定教科書は取り扱っていないので注意しましょう。
例えば東京圏であれば、神保町三省堂書店や、または第一教科書<ref>JR中央線大久保駅南口にある。東京都新宿区百人町1丁目22-20</ref>などで購入や注文が行えます。
{{コラム|教科書の価格|定価については[https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm こちら]に記載されている値段と同じである。小学校・中学校の各教科で出版社に関係なく価格が固定されており、1つの教科書の値段が最も安いもので1冊約150円 <!-- 小学校書写 -->、最も高いもので1冊約1,350円<!-- 高校地図 ※専門分野の教科書は対象外とした場合-->までさまざまである。なお1つの教科書が複数冊になっている場合(上巻と下巻、教科書と教科書準拠ノートなど)は、それぞれの価格の合計が決まった価格となっている。|}}
{{コラム|教科書の購入時期|教科書は、普通3月~4月上旬、あるいは8月~9月上旬に学校に配布される。当然児童・生徒への配布が最優先であるため、一般向けへの配布はやや遅れる。規定により、小中学校の1冊で構成されている教科書や2冊制の教科書の上巻(前期通年用)は4月16日から、2冊制の教科書の下巻(後期用)は9月16日より販売となる。}}
{{コラム|2020年度の小学校教科書の使用|小学校4年の社会は、2019年度に3年の教科書とともに配布された教科書を使うため2020年は発行されない。また、学習指導要領での記述が2学年ごとになっているが、教科書は学年ごとに発行される国語・書写・生活・音楽・道徳において、偶数学年については、旧教科書を使用することも可能である。}}
=== 検定教科書の閲覧方法 ===
教科書を購入せずに閲覧したい場合、あるいは過去に出版された教科書を閲覧したい場合の方法を紹介します。
まず、その地域の図書館を利用してみましょう。市区町村の図書館には、その市区町村立小・中学校で使用している教科書(およびほかの教科書)を置いていることがあります。地域により異なりますが、借りることが出来る場合があるので、興味があるなら図書館に行ってみるとよいでしょう。
また、[[w:国立国会図書館]]([[w:国際子ども図書館]])を利用する方法があります。国会図書館に行けば、余程のことがない限り全ての教科書を閲覧することが出来ます。探している教科書がどうしてもない場合は、活用してみると良いでしょう。
さらに、教科書採択を実施する年には、6月12日~7月31日までの任意の14日間ほど、各都道府県の施設で住民に採択する教科書についての意見を聞くための教科書展示会が行われるため<ref>実施機関や教科書の種類などは都道府県によって異なるので、各都道府県のホームページなどを参考にしてください。</ref>、教科書の見本を閲覧することが出来ます。ただし、本来の目的は住民に意見を問うことであるため、できれば閲覧した後に意見などを書いておきましょう。
なお、各教科書会社のホームページにアクセスすると教員向けの「年間指導計画」を見ることが出来ます(教員でなくても見られる場合がほとんどです)から、それを閲覧することで大まかな内容を知ることが出来ます。
==特殊な教科書==
=== 小・中学の副読本 ===
小学校・中学校の、学校で配られるような、教科書準拠の資料集やワークブック類などの副読本の多くは、原則的として一般人は購入できない<ref>書店に並んでいるワークブック類は、学校配布ワークブックとは別のワークブックの場合が多い。</ref>。これら学校配布の副読本は、行政的に流通が規制されていたり、または出版元・販売元である学校配布教材の教材会社が、教科書取扱店での市販に消極的であったりする。なので、もし私たち一般人が教科書取扱店で注文しても、その地域の小学校・中学校の教員による許可がないと中間業者が注文を受け付けず、担当科目の教員でない一般人は購入できないのが通常である。
ところで、もし研究目的の編集者で教材を購入する場合、いくつかの教科では検定教科書だけではなく副読本などの別教材も確認する必要がある。
また、一見すると検定教科書に見えても、分類上は検定教科書でない教材もある。例えば、体育実技のための学校配布の書籍(いろんなスポーツのルールや練習例の写真・イラストのある本)は、教科書会社発行の副読本である。保健体育の検定教科書では、保健分野と体育理論のみとなる<ref>規定により、体育実技は取り上げてはいけないことになっているため。</ref>。
=== 中高一貫校での教科書 ===
中高一貫校(おもに中学部)などでは検定教科書を配布のみ行い使用せず、「中高一貫校専用の教科書」を用いる場合がある(検定教科書ではない)。代表的なものに、「体系数学」「NEW TRESURE」「PROGRESS IN ENGLISH」などがある。このようなものは、やや規模の大きな書店などで購入できる(実際に学校で使用されているものと比較するとデザインがわずかに異なる場合がある。また、学校独自の教科書である場合もあるので注意すること)。なお、学校独自の教科書を用いている場合もあり、それに関してはほとんど購入不可能である。
== 教科書番号 ==
[[w:教科書番号|教科書番号]]とは、文部科学省が小中学校・高等学校の検定教科書に割り振っている番号のことです。出版社名(略称)と発行者の番号<ref name="hako-no">ISBNの出版社記号とは別物である。また、1番から233番のすべてに対応している教科書会社があるが、「すでに教科書事業から撤退したもの(廃業したもの)」、「現在採択されていないもの」、「特別支援学校の教科書のみを作成しているもの」については記載していない。</ref>・教科/科目名と3ケタの数字で構成されています。
各検定教科書については[[/小中学校|小中学校の教科書について]]、[[/高等学校|高等学校の教科書について]]をご覧ください。
=== 2023年度発行者リスト ===
(現在、新課程版に改定作業中です。改訂作業をお手伝いいただける方はご協力ください。)
以下、出版社名にあるリンクは、その出版社の公式ホームページ(の教科書ページ)のものです。連絡先やなどは、当該ぺージを参考にしてください。
<!-- 発行者名は「教科書表紙に記載のもの」と統一しています -->
{| class="wikitable sortable"
|-
! 発行者<br>番号<ref name="hako-no"/>!! 発行者<br>略称 !! 出版社名
! style="width:18em"|発行教科書(小学校)
! style="width:18em"|発行教科書(中学校)
! style="width:18em"|発行教科書(高等学校)
|-
|2||東書||[https://www.tokyo-shoseki.co.jp/ 東京書籍]|| 国語・書写・社会・地図・算数・理科・生活・家庭・保健体育・英語・道徳 || 国語・書写・社会(地理・歴史・公民)・地図・数学・理科・保健体育・技術・家庭・英語・道徳 || 国語・地歴(世界史・日本史・地理)・地図・公民(政治経済・倫理・公共)・地図・数学・理科・芸術(書道)・英語(コミュニケーション・表現・会話)・家庭(一般教科)・情報(社会・科学)
|-
|4||大日本||[https://www.dainippon-tosho.co.jp/ 大日本図書]|| 算数・理科・生活・保健体育 || 数学・理科・保健体育
|style="background-color:#777" |(なし)
|-
|6||教図||[https://www.kyoiku-tosho.co.jp/index_top.php 教育図書]
|style="background-color:#777" |(なし) || 技術・家庭 ||芸術(書道)・家庭(一般教科)・家庭(専門教科)・公民(公共)
|-
|7||実教||[http://www.jikkyo.co.jp/ 実教出版]
|style="background-color:#777" |(なし)
|style="background-color:#777"|(なし) || 地歴(世界史・日本史)・公民(公共・政治経済・倫理)・数学・理科・家庭(一般教科)・情報(社会・科学)・農業・工業・商業・水産・家庭(専門教科)・福祉
|-
|9|| 開隆堂 ||[https://www.kairyudo.co.jp/ 開隆堂]|| 図画工作・家庭・英語 || 美術・技術・家庭・英語 || 英語・家庭(一般教科)・情報(社会)
|-
|11|| 学図 ||[https://gakuto.co.jp/ 学校図書]|| 国語・書写・算数・理科・生活・英語・道徳 || 国語・書写・数学・理科・英語・道徳
|style="background-color:#777" |(なし)
|-
|15|| 三省堂 ||[https://tb.sanseido-publ.co.jp/e-school/ 三省堂]|| 英語 || 国語・書写・英語 || 国語・英語(コミュニケーション・表現・会話)
|-
|17|| 教出 ||[https://www.kyoiku-shuppan.co.jp/ 教育出版]|| 国語・書写・社会・算数・理科・生活・音楽・英語・道徳 || 国語・書写・社会(地理・歴史・公民)・数学・理科・英語・音楽(音楽・器楽)・道徳 ||芸術(音楽・書道)
|-
|26|| 信教 ||[http://www.shinkyo-pub.or.jp/ 信州教育出版社]|| 理科・生活
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)
|-
|27|| 教芸 ||[https://www.kyogei.co.jp/ 教育芸術社]|| 音楽 || 音楽(音楽・器楽) || 音楽
|-
|35|| 清水 ||[http://www.shimizushoin.co.jp/ 清水書院]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)<ref name="-2021">中学生の教科書は2021年で出版を終了した。</ref>
| 歴史(日本史探究・歴史総合)・公民(公共・政治・倫理)
|-
|38|| 光村 ||[https://www.mitsumura-tosho.co.jp/ 光村図書]|| 国語・書写・生活・英語・道徳 || 国語・書写・美術・英語・道徳 || 芸術(書道・美術)
|-
|46|| 帝国 ||[https://www.teikokushoin.co.jp/ 帝国書院]|| 地図 || 社会(地理・歴史・公民)・地図 || 地歴(地理総合・地理探究・歴史総合・世界史探究)・公民(公共)・地図
|-
|50|| 大修館 ||[https://www.taishukan.co.jp/kyokasho/ 大修館書店]
|style="background-color:#777" |(なし)|| 保健体育 || 国語・保健体育・英語(コミュニケーション・表現)・家庭
|-
|61|| 啓林館 ||[https://www.shinko-keirin.co.jp/keirinkan/index.html 啓林館]|| 算数・理科・生活・英語 || 数学・理科・英語 || 数学・理科・英語(コミュニケーション・表現・会話)
|-
|81|| 山川 ||[https://www.yamakawa.co.jp/ 山川出版社]
|style="background-color:#777" |(なし)
||社会(歴史)||地歴(歴史総合・世界史探究・日本史探究)
|-
|89|| 友社 ||[https://www.ongakunotomo.co.jp/ 音楽之友社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)|| 芸術(音楽)
|-
|104|| 数研 ||[https://www.chart.co.jp/ 数研出版]
|style="background-color:#777" |(なし)|| 数学 || 国語・公民(公共・倫理・政治・経済)・数学・理科・英語(コミュニケーション・表現)・情報(社会・科学)
|-
|109|| 文英堂 ||[https://www.bun-eido.co.jp/products/?menu=5&submenu=128 文英堂]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)|| 国語・英語(コミュニケーション・表現・会話)
|-
|116|| 日文 ||[https://www.nichibun-g.co.jp/ 日本文教出版]|| 書写・社会・算数・生活・図画工作・道徳 || 社会(地理・歴史・公民)・数学・美術・道徳 || 芸術(美術・工芸)・情報(社会・科学)
|-
|117|| 明治 ||[https://www.meijishoin.co.jp/ 明治書院]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語
|-
|130|| 二宮 ||[http://www.ninomiyashoten.co.jp/ 二宮書店]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 地理・地図
|-
|143|| 筑摩 ||[http://www.chikumashobo.co.jp/ 筑摩書房]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語
|-
|144|| 暁 ||[https://www.akatsuki-shuppan.co.jp/ 暁出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 商業
|-
|154|| オーム ||[https://www.ohmsha.co.jp/tbc/ オーム社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 工業
|-
|174|| コロナ ||[https://www.coronasha.co.jp/ コロナ社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 工業
|-
|177|| 増進堂 ||[https://www.zoshindo.co.jp/ 増進堂(受験研究社)]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(コミュニケーション・表現)
|-
|178|| 農文協 ||[http://www.ruralnet.or.jp/ 農山漁村文化協会]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 農業
|-
|179|| 電機大 ||[https://www.tdupress.jp/ 東京電機大学]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 農業・水産・工業
|-
|183|| 第一 ||[http://www.daiichi-g.co.jp/ 第一学習社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語・地歴(歴史総合・探究・地理総合)・公民・数学・理科・英語・家庭(一般教科)・保健体育・情報(社会・科学)
|-
|190|| 東法 ||[https://toho.tokyo-horei.co.jp/ 東京法令出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 商業・公民(公共)
|-
|201|| 海文堂 ||[http://www.kaibundo.jp/ 海文堂出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 農業・水産
|-
|205|| 三友 ||[http://sanyusha-shuppan.com/forteacher/textbook/ 三友社出版]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(コミュニケーション・表現)
|-
|207|| 文教 ||[http://www.bunkyosya.co.jp/ 文教社] || 保健体育
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)
|-
|208|| 光書 ||[https://www.kobun.co.jp/textbook/ 光文書院] || 保健体育・道徳
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし)
|-
|212|| 桐原 ||[https://www.kirihara.co.jp/ 桐原書店]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語・英語(コミュニケーション・表現)
|-
|218|| 京書 ||[https://www.kyo-sho.com/ 京都書房]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 国語
|-
|220|| スクリ ||[https://www.screenplay.jp/text スクリーンプレイ]<ref>現・株式会社フォーインスクリーンプレイ</ref><ref name="-2020">2020年で出版を終了する。</ref>
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(表現)
|-
|221|| 明成 ||[https://meiseisha.com/%e6%95%99%e7%a7%91%e6%9b%b8-2/ 明成社]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 地歴(日本史)
|-
|224|| 学研 ||[https://gakkokyoiku.gakken.co.jp/ 学研教育みらい]|| 保健体育・道徳 || 保健体育・道徳
|style="background-color:#777" |(なし)
|-
|225|| 自由社 ||[http://www.jiyuusha.jp/newpage28..html 自由社]
|style="background-color:#777" |(なし) || 社会(歴史・公民)
|style="background-color:#777" |(なし)
|-
|226|| チアーズ ||[https://atlantisenglish.com/ CHEERS]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(コミュニケーション・表現・会話)
|-
|227|| 育鵬社 ||[http://www.ikuhosha.co.jp/ 育鵬社]
|style="background-color:#777" |(なし) || 社会(歴史・公民)
|style="background-color:#777" |(なし)
|-
|228|| 山下 ||山下 明 <ref>個人出版である。[https://www.osaka-cu.ac.jp/ja/news/2012/a4yqqo 参考サイト]</ref><ref name="-2020"></ref>
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 工学
|-
|229|| 学び舎 ||[http://manabisha.com/ 学び舎]
|style="background-color:#777" |(なし) || 社会(歴史)
|style="background-color:#777" |(なし)
|-
|230|| ネット ||[https://book.net-school.co.jp/zensho/ ネットスクール]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 商業
|-
|231|| いいずな ||[https://www.iizuna-shoten.com/ いいずな書店]
|style="background-color:#777" |(なし)
|style="background-color:#777" |(なし) || 英語(表現・英語コミュニケーション)
|-
|232|| 廣あかつき ||[https://www.kosaidoakatsuki.jp/ 廣済堂あかつき]|| 道徳 || 道徳
|style="background-color:#777" |(なし)
|-
|233|| 日科 ||[http://www.nihon-kyokasho.co.jp/ 日本教科書]
|style="background-color:#777" |(なし)|| 道徳
|style="background-color:#777" |(なし)
|-
|234
|TAC
|[https://shuppan.tac-school.co.jp/koukou/ TAC出版]
|
|
|商業
|-
|235
|CUP
|
|
|
|英語(英語コニュニケーション)
|-
|}
==脚注==
<references/>
==参考・関連項目==
* [[小学校・中学校・高等学校の学習]]
* [https://www.mext.go.jp/a_menu/shotou/kyoukasho/mokuroku.htm 教科書目録(発行予定の教科書の一覧)],文部科学省.
* [https://www.aomoritosyo.co.jp/kyoukasho/tokuyaku/ 全国教科書取扱特約店一覧(青森県図書教育用品)] 全国の教科書販売店の一覧
* [http://www.daiichikyokasho.co.jp/ 第一教科書] 教科書・問題集直売店「第一教科書」
*[https://www.hirokyou.co.jp/ 広島教販] 教科書ネット通販「広島県教科用図書販売株式会社(広島教販)」
* [https://www.mext.go.jp/a_menu/shotou/kyoukasho/tenji/1359114.htm 2022年教科書展示会について(文部科学省)] - 現在は全都道府県で終了しています。
* [http://www.text-kyoukyuu.or.jp/ 社団法人 全国教科書供給協会] 教科書の価格、教科書発行者一覧など教科書に関する情報を載せる
{{DEFAULTSORT:けんていきようかしよ}}
[[Category:普通教育]]
m071sxv4blgfx84zu52duiqxv3f9i80
Kotlin/実行方法
0
28987
205824
186894
2022-07-25T07:04:03Z
Ef3
694
/* GNU/Linuxの場合 */ シェルスクリプトの実行にsourceビルトインコマンドを使ってはいけない。なぜなら、シェル変数やシャル関数を汚染してしまうからである。この例で言えば filename がこれにあたる。sourceは、.bash_profile を書き換えた時にログアウト/ログインを行わず変更を反映させるなどのためにあり、シェルスクリプトを実行する用途は想定されていない(シェルスクリプトは、もう1つ別のプロセスのシェルをforkすることでアイソレーションされた状態で実行している)。
wikitext
text/x-wiki
== 注釈 ==
Kotlinは、コンパイルのターゲットごとに大別すると
* [[JavaScript]]向けであるKotlin/JS
* [[w:Java仮想マシン]]向けのKotlin/JVM
* [[w:iOS]]、[[w:Linux]]、[[w:Mac OS]]、[[w:Windows]]、[[w:WebAssembly]]向けのKotlin/Native
がある。
それぞれのターゲットで標準ライブラリの関数が存在しない場合や、シグニチャが異なる場合があるため、疑義が生じた場合はJetBrainsのマニュアルを参照のこと。
== Kotlin/JVM ==
=== 実行方法 ===
hello.kt のように、ファイル名の末尾に拡張子{{code|.kt}}をつける。Windows版に拡張子が必要なのは当然として、Linux版kotlin用のファイルでも拡張子.kt をつける必要がある。(※ Fedora32で2020年6月に確認. Windows版kotlinも同様)
さてWindows版でもLinux版でも、コマンド
kotlinc ファイル名.kt -include-runtime -d ファイル名.jar
で[[w:.jar|jar形式]]にコンパイルできる。
たとえば、ソースコードのファイル名が hello.kt なら
kotlinc hello.kt -include-runtime -d hello.jar
になる。
Kotlin を Java仮想マシンで動作させる場合には、Java仮想マシンが解釈できるjar形式に変換する必要がある。
hello.jar を作成してから、jarファイルを実行する。
kotlin hello.jar
で実行できる。
つまり、
kotlin ファイル名.jar
である。
まとめると、
<pre>
kotlinc ファイル名.kt -include-runtime -d ファイル名.jar
kotlin ファイル名.jar
</pre>
で実行することができる。
=== シェルスクリプトで実行する場合 ===
コマンドラインの作業を、シェルスクリプトという技法を使うことで自動化できる。
Kotlinの作業の場合、コンパイルのコマンドが長くなるので、手打ちで毎回、コマンドを入力するのは、だいぶ面倒である。
(すべてのファイル名を「hello.kt」で使い回せば、コマンド手打ちの必要は無くなるが、しかし実務では管理上の問題を引き起こしかねない。そこで、シェルスクリプトが便利である。)
ただし、そのOSに付属したシェルスクリプト実行ツールが必要である。
==== GNU/Linuxの場合 ====
GNU/Linuxの場合、メジャーなLinuxディストリビューションに Bash (バッシュ)というシェルが入っているので、シェルスクリプトでBashに命令スクリプトを与えて自動化できる。
;GNU/Linuxの場合のコード例(シェルスクリプト)
<syntaxhighlight lang="bash">
#!/bin/bash
filename="hello"
kotlinc ${filename}.kt -include-runtime -d ${filename}.jar
kotlin ${filename}.jar
</syntaxhighlight>
;実行方法
コマンド
bash シェルスクリプトのファイル名.sh
<!-- シェルスクリプトの実行にsourceビルトインコマンドを使ってはいけない。なぜなら、シェル変数を汚染してしまうからである。この例で言えば filename がこれにあたる。
またはsourceコマンドを使い、
source シェルスクリプトのファイル名.sh
のように入力すればいい。
シェルには、bash以外にもzshやcshなど様々なシェルがあるので、そのようにbash以外のシェルを使う場合にはコマンド「bash」は当然、使えない。
-->
;解説
冒頭の1行目の
:<code>#!/bin/bash</code>
は[[Shebang]といい、スクリプトを実行するインタープリタ(この場合は /bin/bash )の所在を指定する。
bash のプロンプトから、bash のスクリプトを実行する場合は、Shebangがなくても同じ様に bash で実行されるが、bash 以外のシェル(例えば、tcsh)からShebangのないbashのシェルスクリプトを実行しようとすると、tcsh のシェルスクリプトとして実行されてしまい、期待した結果は得られない。
このように、
次に、2行目
:<code>filename="hello"</code>
でシェル変数「filename」に文字列「hello」を代入している。
注意点として、けっして
:<code>filename = "hello"</code> ※ ダメな例
のようにスペースを空けてはならない(イコールの前後などにスペースを空けてはいけない。)。もしスペースを空けてしまうと、代入ではなくコマンド「filename」として認識してしまい、エラーメッセージ「行 2: filename: コマンドが見つかりません」のようにエラーになってしまう。
このファイル名"hello"の部分を、hello以外のファイルのコンパイルなどを自動化したい場合には、都度スクリプトファイルにハードコードされたファイル名を書き変えるのではなく、コマンドライン引数や環境変数を使ってスクリプトにファイル名を渡すべきであろう。
また、シェルスクリプトによる方法では、変更のないソースコードまでコンパイルしてしまうので、makeやantの様なビルドツールを使うことも検討に値する。
==== Windowsの場合 ====
コマンドプロンプトではバッチファイルというのが使える。
;バッチファイルのコード例
<syntaxhighlight lang="bat">
set filename=hello
call kotlinc %filename%.kt -include-runtime -d %filename%.jar
call kotlin %filename%.jar
</syntaxhighlight>
;解説
実は、Windowsにおけるkotlincコマンドおよびkotlinコマンドの正体はバッチファイルである
そして、Windowsのバッチファイルは、バッチファイルから他のバッチファイルを呼び出すと、そこで呼び出さされたバッチファイルを実行したら、標準の仕様では動作が終了してしまう仕様である。
この終了を回避するには、call キーワードを使って、バッチファイルを呼び出さなければいけない。
;注意点
代入する文字列「hello」などに引用符はつけない。
変数の呼び出しは、「%変数名%」のように「%」で囲む。
;PowerShellの方法
Windowsの場合、PowerShellというのがWindows7以降の最新バージョンには入っているので、そのPowerShellというのを使ってシェルスクリプトを書けばいいのだが、しかしセキュリティ上の理由でWindowsでは標準設定ではPowershellシェルスクリプトの実行が出来ないようになっている。
なので、バッチファイルを使うか、いっそWindowsよりもLinuxでシェルスクリプトを実行するほうが良い。
== 参考: Hello World ==
実行対象のファイルの例として、Hello World のコードを示す。(文法の単元で説明しているコードと同じ内容。)
<syntaxhighlight lang="Kotlin">
// Hello.kt
fun main(args: Array<String>) {
println("Hello, World!")
}
</syntaxhighlight>
1g111y1dfb3vfn444r141sp2qa8dbnv
病理学/血液・造血器・リンパ節
0
29620
205803
168853
2022-07-25T00:07:29Z
はいかぐら
45848
wikitext
text/x-wiki
== 前書き ==
赤血球は、骨髄にある造血幹細胞から作られる。(「肝」細胞ではなく「幹」細胞なので、誤字に注意。)
さて、白血球やT細胞とB細胞も、同じく骨髄の造血幹細胞から作られる。
なお、説明の簡素化のため「白血球」と言ったが、好中球、好酸球、好塩基球のことである。
リンパ球とは、T細胞およびB細胞のことである。
※ このため、「造血」などの単元では、医学書でも、赤血球や血小板と言った血液成分だけでなく、白血球やリンパ球も扱う。
== 貧血 ==
医学における「貧血」とは、正常なヘモグロビンの血液濃度が低下して、正常範囲のヘモグロビン濃度には足りない事を言う。
しかし便宜上、出血などによって血液自体が不足している場合でも貧血という場合がある<ref>『標準病理学』、P307、節『赤血球喪失による貧血』</ref>。
なので『シンプル病理学』では、『貧血』とは、血液中の赤血球またはヘモグロビンが減少する事、という風な定義をしている。
:※ この単元では、特に断らないかぎり、『貧血』とは、血液中のヘモグロビン濃度が病的に低い事だとする。(出血については、科目『救急医学』などの話題だろう)
:※ たとえ、血栓など循環障害による虚血やチアノーゼなどが起きていても、ヘモグロビン濃度が低くなければ、上記のような定義では『貧血』とは呼ばない<ref>『スタンダード病理学』</ref>。
成人男性の健常者は、ヘモグロビン濃度 14~18g/dLである<ref>『スタンダード病理学』</ref>。なので成人男性ではヘモグロビン濃度が 約12.5g/dL以下から貧血とみなされる<ref>『標準病理学』</ref>。
成人女性の健常者は、ヘモグロビン濃度 12~16g/dLである<ref>『スタンダード病理学』</ref>。なので成人女性ではヘモグロビン濃度が 約11.5g/dL以下から貧血とみなされる<ref>『標準病理学』</ref>。
== 貧血の種類 ==
貧血には、下記の種類がある。
=== 赤血球の喪失による貧血 ===
(便宜上なのか、)出血によって赤血球を喪失した場合も「貧血」といい、医学書ではそのまま「赤血球の喪失による貧血」などのように言う。
=== 鉄欠乏性貧血 ===
鉄はヘモグロビンの主な原料なので、鉄が欠乏するとヘモグロビンが合成されずに貧血になる。
食事において、鉄摂取が不足すると発生しやすい。
成長期や妊娠において、鉄需要の増大により、鉄欠乏性貧血が発生しやすい。
なんらかの鉄吸収阻害の障害があると発生しやすい。
慢性出血による「貧血」は、これに含める。(※ 濃度はともかく、どのみち体内の鉄分も不足する。)
=== 再生不良貧血 ===
骨髄にある、造血幹細胞の異常であり、予後は悪い。骨髄が低形成であり、脂肪で骨髄が置き換えられている(「脂肪髄」という)。
赤血球のみでなく、白血球や血小板も減少している(「汎血球減少」という)。
=== 巨赤芽球性貧血 ===
赤芽球とは、造血幹細胞から派生した、赤血球のもととなる細胞である<ref>『標準病理学』、第8版、P515</ref>。
ビタミンB<sub>12</sub>欠乏あるいは葉酸欠乏でも起きる。
症状は、(赤芽球ではなく)赤血球が巨大化、または赤血球の奇形などの症状である<ref>『スタンダード病理学』</ref>。
原因としては、赤血球の成熟に必要なDNAがビタミンB<sub>12</sub>不足などで合成されず、RNAやタンパク質だけが合成されていった結果、
赤血球の巨大化や奇形などが生じている<ref>『スタンダード病理学』</ref>と考えられている。
なお、ビタミンB<sub>12</sub>は小腸で吸収されるが、
胃粘膜から産生される内因子がビタミンB<sub>12</sub>の吸収に必要なので、胃切除の手術などで、発生しやすい。
'''悪性貧血'''とは、なんらかの理由で(たとえば自己免疫疾患として内因子を抗体が攻撃してしまう機構が考えられている<ref>『標準病理学』</ref><ref>『シンプル病理学』</ref>)、その結果として胃の内因子が作られなくなり、巨赤芽球性貧血を起こす事を言う。
=== 遺伝性球状赤血球症 ===
赤血球は健常なら、円盤状である。
しかし、遺伝性球状赤血球症では、赤血球が球状である。常染色体優性遺伝である。
この病気だと、赤血球の寿命が短く、そのため間接ビリルビンの上昇を示す。
溶血性貧血に分類される。
:※ なんらかの理由で、赤血球が破壊されてしまっていると考えられている。
白色人種に多い<ref>『スタンダード病理学』</ref>。
:※ 医学では「コーカソイド」などとは言わず、「白色人種」と言う。
ビリルビンが増加しているため、黄疸が見られる<ref>『スタンダード病理学』</ref><ref>『図解ワンポイントシリーズ3 病理学』</ref>。
== 発作性夜間ヘモグロビン尿症 ==
血管内溶血により、ヘモグロビン尿が発生する。
赤血球の膜に異常があり、この異常により溶血が起きやすくなっている。
「夜間」と名前が入っているが、実際には発作が起きる時刻が夜間とは限らない<ref>『標準病理学』</ref>。
近年、この症状の原因がPIG-A遺伝子(ホスファチジルイノシトールグリカン-クラスA)の異常である事が明らかになった。
== 鎌状赤血球症 ==
ヘモグロビンの構造異常であり、原因は、突然変異により、βグロビンの本来ならグルタミン酸であるべき部分がバリンに置換している事。
この構造異常により、溶血性貧血を起こす。
常染色体劣性遺伝である。
== 白血病 ==
白血病は、造血細胞の腫瘍性疾患である<ref>『シンプル病理学』</ref><ref>『図解ワンポイントシリーズ3 病理学』</ref><ref>『標準病理学』</ref>。
:※ 分類上、白血球の数や状態は、その症状が「白血病」かどうかとは、あまり関係ない。
:※ 歴史的には、1800年代に白血病の先駆的な研究をしていたウィルヒョウの研究していた白血病患者の腫瘍の種類が、たまたま、おそらくは、骨髄の白血球系統の腫瘍だったためか、患者血液では白血球が異常に増加しており、ウィルヒョウが血液分析をすると血液中に白い部分が見えたので、「白血病」という名前になっているらしい。
:※ 『シンプル病理学』改訂第4版(2005年)を見ると、「白血病」について「白血球系」の「腫瘍」と限定しているのは、こういう歴史的なウィルヒョウの当初の事例のこと。現代では、白血球に限定せず、骨髄の造血細胞の腫瘍一般を「白血病」とする。
:※ このため、もし赤血球の異常であっても、原因が骨髄腫瘍であれば、「白血病」に含める。その他、B細胞やT細胞などのリンパ球も、その前駆細胞はもとをたどれば骨髄で作られる造血幹細胞なので、よって「白血病」には、骨髄腫瘍が原因の場合でのB細胞およびT細胞と言ったリンパ球の異常の場合も含む。)
白血病は、腫瘍化した細胞の起源から、骨髄性白血病とリンパ性白血病との2種類のいずれかに分類される。
なお、白血病の分類として、French-American-British分類(FAB分類)がある。
急性白血病では、FAB分類が主に用いられている。
その他の分類として、WHOが白血病の分類を出しており、たとえばWHO分類の第4版が2008年に出された。
{| class="wikitable" style="float: right; text-align: center; margin: 2pt;"
|-
! style="text-align: center;" | 名称 !! 型 !! 所見
|-
| 急性骨髄芽球性白血病 || M0, M1, M2 ||
|-
| 急性前骨髄腫性白血病 || M3 ||
|-
| 急性骨髄単球性白血病 || M4 ||
|-
| 急性単球性白血病 || M5a, M5b ||
|-
| 赤白血病 || M6 ||
|-
| 急性巨核芽球性白血病 || M7 ||
|-
|}
=== 急性 ===
急性骨髄性白血病では、FAB分類のよりM0からM7までの8型に分類される。
;急性骨髄芽球性白血病
FAB分類では、M0からM2までである。
;急性前骨髄腫性白血病
M3である。
:(※ 調査中:) 「アウエル小体」というのが認められる<ref>『シンプル病理学』</ref><ref>『図解ワンポイントシリーズ3 病理学』</ref><ref>『標準病理学』</ref>。
;急性骨髄単球性白血病
M4である。
;急性単球性白血病
M5である。M5aは単芽球の未分化型。M5bは分化型。
;赤白血病
M6。赤芽球の増殖が顕著。骨髄の赤芽球性の腫瘍だと考えられている<ref>『スタンダード病理学』</ref>。
;急性巨核芽球性白血病
M7。
=== 慢性骨髄性白血病 ===
:※ 医学書では、造血幹細胞の腫瘍の異常だとしているが、それだと急性との区別がつかないので、当wikiでは定義の説明を差し控える。詳細は医学書で確認せよ。
現在、「慢性骨髄性白血病」と言われている症状では、ほとんどの患者に'''フィラデルフィア染色体'''(Ph<sup>1</sup>染色体)という異常染色体が見られる。
フィラデルフィア染色体は、第22番染色体および第9番染色体に由来している。フィラデルフィア染色体とは、第22番染色体のBCR遺伝子 と 第9番染色体のABL遺伝子 が相互に転座したもの。
一説には、この転座のため、異常にチロシンキナーゼ活性が強まっているのが、慢性骨髄性白血病の発症に関わっていると考えられている。<ref>『スタンダード病理学』</ref><ref>『標準病理学』</ref><ref>『シンプル病理学』</ref>。
:※ もともと、BCR遺伝子およびABL遺伝子はチロシンキナーゼの活性に関わっている。
この異常のため本症例の患者では、顆粒球が著名に増えていおり、好中球、好塩基球、好酸球が多い<ref>『標準病理学』</ref>。
経過中、急性白血病の病症に転化する場合もあり、'''急性転化'''という。
かつては予後不良の病気であったが、イマチニブの発明とその投与により、予後は改善されてきた。
== 「骨髄腫」 ==
まぎらわしい事に、「骨髄腫」とは骨髄の腫瘍ではない。
「骨髄腫」とは、癌化したB細胞によって異常な免疫グロブリン抗体(「'''Mタンパク'''」という)が産生され続けてしまうという病気である<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref>。
:※ 定義上、必ずしも異常B細胞の産生の場所は骨髄でなくても良いが、「骨髄腫」でも普通は骨髄でB細胞の前駆細胞が産生されるハズ><ref>『図解ワンポイントシリーズ3 病理学』</ref>。
健常な免疫グロブリン抗体とは異なり、Mタンパクは単クローン性である。
また、尿中に、免疫グロブリンの軽鎖の二量体を多く含むタンパク質である'''ベンスジョ-ンズ タンパク'''が多く出現してくる。
また、骨のX線写真(いわゆる「レントゲン」)で、骨に穴が空いたような像がよく見られ、これを「'''打ち抜き像'''」という。
骨が破壊・融解されて、打ち抜き像が発生している。
患者は中年以降に多く、40歳ごろから発症してきて、<ref>『スタンダード病理学』</ref><ref>『シンプル病理学』</ref>。
ピークは60歳代である<ref>『スタンダード病理学』</ref>と言われている。
性比では、男性に多い<ref>『スタンダード病理学』</ref><ref>『図解ワンポイントシリーズ3 病理学』</ref>。
== マクログロブリン血症 ==
:※ 『標準病理学』には、マクログロブリン血症の記載は無い。
マクログロブリンとは、免疫グロブリンのIgM抗体のこと<ref>『標準病理学』</ref>。
ヒトの免疫グロブリンでは、
5つある抗体のうち、最も分子サイズの大きいのがIgM抗体なので、IgM抗体には「マクログロブリン」という別名がある<ref>『スタンダード病理学』</ref>。
マクログロブリン血症とは、B細胞の腫瘍により、IgM抗体ばかりを産生する症状。
== 突発性血小板減少紫斑病 ==
血小板が減少する。
急性型と慢性型がある。小児は急性型であり、ウイルス感染のあとに見られる事が多く、6ヶ月<ref>『標準病理学』</ref>以内で自然治癒しやすく予後は良い。
成人には、6ヶ月を超える慢性型が多い。
原因として、血小板に対する自己抗体が作られてしまっていると考えられている。自己免疫疾患のひとつと考えられている<ref>『スタンダード病理学』</ref>。脾臓で抗体に覆われた血小板が貪食されていると考えられている。
== 本態性血小板血症 ==
血小板が増加しており、WHOの診断基準では45万/μLを超えるものを言う<ref>『標準病理学』</ref>。
巨核球の増生も見られる。
症状として、繰り返す血栓症<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref>、および出血症状がある<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref><ref>『シンプル病理学』</ref>。
本患者の骨髄には細胞成分が多く<ref>『スタンダード病理学』</ref>、造血細胞が増加している<ref>『標準病理学』</ref>。骨髄では脂肪成分が激減していて少ないが<ref>『標準病理学』</ref>、ある程度は脂肪成分が残存しているる<ref>『スタンダード病理学』</ref>。
== 血友病 ==
:※ 単元『[[病理学/先天異常#X連鎖劣性遺伝病]]』で血友病の遺伝性については説明ずみ。
血液凝固因子(第VIII因子(8)や第IX因子(9)<ref>『スタンダード病理学』</ref> )の欠損や異常のために血が固まりにくい病気であり、そのため怪我などをして出血したとき、止血されにくく治りにくい病気である。
血友病Aと血友病Bがある。第8因子の欠乏しているものが血友病Aである。第9因子の欠乏しているものが血友病Bである。
日本では、血友病Aのほうが発生頻度が大きく<ref>『スタンダード病理学』</ref><ref>『標準病理学』</ref>、だいたい A患者:B患者 の比率が 5:1 の比率だと言われている<ref>『スタンダード病理学』</ref>。
薬害問題では過去に、血友病の非加熱製剤がAIDSの感染源になった社会問題が起きた事がある<ref>『スタンダード病理学』</ref>。
== 骨髄異形成症候群 ==
骨髄異形成症候群は、WHO分類でもFAB分類でも、幾つかの病例に分類される。
:※ おそらく、この症候群は一つの病気ではなく、幾つかの病気をまとめたものだと考えられる。
:※ 『標準病理学』はWHO分類、『スタンダード病理学』はFAB分類で説明。
かつてより「前白血病」などと呼ばれていた。
WHO分類とFAB分類のともに、不応性貧血(RA)と、鉄芽球系の不応性貧血(RARS)、芽球増加を伴う不応性貧血(RAEB)、がある。
== その他 ==
;シェーンラインヘノッホ紫斑病
:※ 『標準病理学』には記載なし。
;結核
結核が骨髄に見られる場合もある<ref>『標準病理学』、第5版、328ページ、</ref>
:※ 白血病の紹介が続いたが、このページは、けっして腫瘍のページではなく、血液・造血器・リンパ節のページなので、感染症でも骨髄やリンパに影響の出てくるものなら紹介する。『標準病理学』でも同様の考え。
== 急性リンパ性白血病 ==
リンパ芽球の腫瘍性の増殖である。
:※ 『シンプル病理学』に急性リンパ性白血病などリンパ系の白血病の記載なし。
B細胞やT細胞を明言せず、単に「急性リンパ性白血病」と言った場合、普通、B細胞性のものを言う。
:※ T細胞性の白血病には、後述のように「T細胞性リンパ芽球性白血病」という別の病気がある。
=== B細胞性リンパ芽球性白血病 ===
小児に多い<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref>。
FAB分類ではL1型に分類される。
=== T細胞性リンパ芽球性白血病 ===
小児のリンパ性の白血病の多くはB細胞性であるが、15%<ref>『標準病理学』</ref>~20%<ref>『スタンダード病理学』</ref>ほどはT細胞性の白血病の小児患者もいる。
また、成人では、T細胞性リンパ性の白血病の患者が多い。
FAB分類ではL2型に分類される。
== リンパ節 ==
:※ 「リンパ腫瘍」とは異なります。「リンパ腫」とは、文脈にもよるが、T細胞やB細胞などといったリンパ球の腫瘍です。
:一方、この節で取り上げるのは、「リンパ節」というリンパ管の経路中にある組織 に病状の出る疾患です。
;リンパ節
そもそもリンパ節とは、リンパ管の経路中にある、大きさがおおむね、米粒大から大豆大までの瘤のような膨らんだ部分。
そのリンパ節の中に、器官組織がある。
:※ 詳しくは(たぶん)生理学の科目で説明する。
リンパ節はそもそも、免疫を助ける機能をしているため、リンパ節の異常と正常との区別がしづらい。
この単元では主に、腫瘍や先天異常などで、リンパ節の機能が働いてない事例と、結核など感染症に対するリンパ節炎を分けて取り上げる。
:※ 『標準病理学』は、結核などのリンパ炎を取り上げていない。『シンプル病理学』『スタンダード病理学』は結核などのリンパ炎を取り上げている。
=== リンパ節の炎症性・反応性の症状 ===
==== 結核 ====
結核で、リンパ節の炎症が見られる。肺門リンパ節が冒されやすい。
他の結核と同様、乾酪壊死やラングハンス巨細胞が見られる場合が多い。
まぎらわしい別の病気として、サルコイドーシス(別の病気)との鑑別が難しい。
==== サルコイドーシス ====
原因不明の、肉芽腫性の疾患。
リンパ節のほか、肺、皮膚、心臓、肝臓、脾臓など全身の各組織に腫瘍が発生する。
(※ 結核と似ている症状だが、しかし結核ではないので、)ツベルクリン陰性である<ref>『スタンダード病理学』</ref>
患者は、20~40歳代に多い<ref>『スタンダード病理学』</ref>。
==== トキソプラズマ性のリンパ節炎 ====
Toxoplasma gondii の感染によって見られる。
:※ 資料不足のため、本wikiでは説明を省略。
:『スタンダード病理学』および『シンプル病理学』に記載あり、
:※ 「リンパ濾胞」の「胚中心」がどうのこうのと、関連書には書いてある。
==== 組織性壊死性リンパ節炎 ====
原因不明。「菊池病」、「菊池・藤本病」などとも言う。
若年者(10~30歳代<ref>『標準病理学』</ref>)に多く、性差はやや女性に多い。
感冒様症状の発熱がある。
主として頚部のリンパ節で腫脹がある。
組織学的に、壊死像が見られる。
==== 皮膚病性リンパ節炎 ====
:※ 資料不足のため、本wikiでは説明を省略。
:『シンプル病理学』には見当たらない。
:『標準病理学』および『スタンダード病理学』に、それらしい病気の解説あり。
==== キャッスルマン病 ====
:※ 『標準病理学』、『スタンダード病理学』、『シンプル病理学』に書いてあるけど、
:説明のポイントが3冊とも大きく違っており、現在のところ文献3冊からは全体像が不明。
=== 悪性リンパ腫 ===
悪性リンパ腫
欧米と日本の違いは下記の通り。
:欧米では、ホジキンリンパ腫が多い。
:日本では、非ホジキンリンパ腫ではT細胞性リンパ腫およびNK細胞性リンパ腫が多い。
:日本では、節外性リンパ腫が多い。
なお、「良性リンパ腫」という病名は無い<ref>『標準病理学』</ref>。
分類として、ホジキンリンパ腫と、非ホジキンリンパ腫の2つに大別される。
非ホジキンリンパ腫には、T細胞性のものとB細胞性のものとNK細胞性のものがある。
==== ホジキンリンパ腫 ====
Pel-Ebstein型の発熱を繰り返す。
:※ 標準病理学だとEの次がpの「Epstein」になっているが、これは誤植だろう。『シンプル病理学』および『スタンダード病理学』では(Pel-)「Ebstein」である。
かつては「ホジキン病」と呼ばれていたが、
近年では、大部分はB細胞性のリンパ腫である事が分かり、
WHOの分類でも「ホジキンリンパ腫」と命名されている。
:※ 分類上、リンパ性白血病との区別とが困難なようで、WHOの分類では包括的にリンパ性白血病とまとめて分類している。<ref>『スタンダード病理学』</ref>
多核の「リード・スタンバーグ細胞」や、単核の「ホジキン細胞」と呼ばれる細胞が観察される。
分類として、
:* 古典型、
:* リンパ球減少型、
:* リンパ球増加型、
:* 混合細胞型、
などに分類される。
==== 成人T細胞白血病/リンパ腫 ====
「成人T細胞白血病/リンパ腫」(Adult T-cell leukemia / lymphoma 、略称: ATLL)で、ひとつの病名。
ヒトT細胞白血病ウイルスI型(HTLV-I)の感染による。
:なお、このヒトT細胞白血病ウイルスI型はレトロウイルスである。レトロウイルスとは、逆転写酵素を持つウイルスのこと。
日本では九州、沖縄に成人T細胞白血病/リンパ腫は多発し、成人に多い。
症状では、リンパ節腫脹、肝腫、脾腫、高カルシウム血症、が見られる<ref>『標準病理学』</ref><ref>『シンプル病理学』</ref>。
大別して、型は
:くすぶり型、
:慢性型、
:急性型、
:リンパ腫型、
の4病型に分類される。
急性型とリンパ腫型の予後は悪い<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref>。
発症年齢のピークは60歳代である<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref>。
感染経路として、母乳<ref>『標準病理学』</ref>を介した母子感染<ref>『標準病理学』</ref><ref>『シンプル病理学』</ref>が考えられているが、
その他の経路として性行為<ref>『標準病理学』</ref>も考えられている。
発生頻度に男女間の性差は特に見られない<ref>『スタンダード病理学』</ref>。
=== バーキットリンパ腫 ===
アフリカに多い、小児のリンパ腫である。
エプスタインバーウイルス(EBウイルス)が影響していると言われている。
赤道アフリカやニューギニアでは、90%超<ref>『標準病理学』</ref>で、エプスタインバーウイルスに感染している。
しかし、他の地域ではそうではない(10~30%程度<ref>『標準病理学』</ref>)。
多数の核分裂像を伴う<ref>『標準病理学』</ref><ref>『スタンダード病理学』</ref>。
病型は大別して、
:アフリカ、ニューギニアの現地型である endemic型、
:自己免疫疾患やAIDSなどの「免疫不全型」、
:突発型・散発型である sporadic 型、
の3病型に分類される。
また、EBウイルスの感染率はそれぞれ、
:現地型であるendemic型で90%超、
:sporadic型は10%程度、
:免疫不全型で30%程度、
である<ref>『標準病理学』</ref><ref>『シンプル病理学』</ref>。
== 脾 ==
健常者では100g~150g程度である。
老朽化した赤血球は、脾で貪食される。
また、脾は胎生期における造血組織<ref>『標準病理学』</ref>。
;形成異常
* 無脾
脾が形成されない場合を言う。
* 多脾
脾が複数個ある場合を言う。
* 副脾
正常の大きさの脾の周囲に、小さな脾臓が出来ている場合があり、これを「副脾」という。
== 胸腺 ==
胸腺に胚中心を伴ったリンパ濾胞が過形成しているものは、重症筋無力症と関係があるとされている。
アジソン病、バセドウ病(甲状腺機能亢進症のひとつ)でも、同様にリンパ濾胞の過形成が見られる<ref>『シンプル病理学』</ref><ref>『スタンダード病理学』</ref>。
;胸腺の腫瘍
「胸腺腫」とは何かについて、
:胸腺の腫瘍すべてを「胸腺腫」と呼ぶべきだという流儀(『標準病理学』はこちら)と、
:胸腺上皮細胞の腫瘍を「胸腺腫」と呼ぶべきだという流儀(『スタンダード病理学』はこちら)
の2通りがある。
:※ 『シンプル病理学』では「胸腺上皮腫瘍」という用語もある。
== 脚注 ==
mfg39x4zmgoxkgug23mkuedqipix0lf
利用者:Kwawe
2
34770
205798
204922
2022-07-24T17:55:04Z
Kwawe
68789
wikitext
text/x-wiki
== Wikibooksの記述では ==
新課程の自然科学全般(物理・化学・生物・地学)、社会科学(公民)、人文科学(地理歴史)全般を記述したいと思います。
物理では、文系の人でも分かるような記述を心がけています。
== 教科書 ==
Wikibooksの教科書目録の作成などを新課程版に更新しています。以降更新は2日ずつになります。
当方、高等学校の旧課程(現高校2年以上)教科書は数学・自然科学(物理・化学・生物・地学)・商業の一部・公民・国語表現・人文科学(地理・歴史)の教科書を持参しています。
2022年からの新課程用(高校1年生)は公共の教科書を持参しています。
j0ysehfgyesz83is51qzcf3pt5pt1k5
高校英語の文法/時制
0
35057
205793
205702
2022-07-24T12:56:23Z
すじにくシチュー
12058
進行形
wikitext
text/x-wiki
=== 時制の一致と話法 ===
==== 時制の一致 ====
===== 時制の一致の原則 =====
ジーニアス、ロイヤル英文法にある典型的な例文だが、
「私は、彼が忙しいと思う」 I think that he is busy.
「私は、彼が忙しいと思った」 I thought that he was busy.
これを分析しよう。主節が「思った」と過去形になると、英語では、従属節の意味が「忙しい」と現在形であっても、主節にあわせて he was busy のように動詞が過去形になります。このような現象を「時制の一致」(じせいのいっち)と言います。
時制の一致が起きるのは、主節が過去形または過去完了形の場合だけである。なお、過去完了形については高校で習う。
つまり、現在形・現在進行形および未来時制・未来完了形では、時制の一致は起きない。
なお、過去から見た過去を言い表す場合は、従属節は過去形のままかあるいは過去完了(大過去)になる。参考書ではいちいち分析しないが、「時制の一致」の観点からも、「大過去」を考えることができる。
従属節が未来系であっても、主節が過去形でありさえすれば、時制の一致は起きる。たとえば例文、
「彼が~するだろうと思う」 I think he will ~.
「彼が遅れるだろうと思った。」 I thought he would ~.
である。
===== 時制の一致の例外 =====
従属節で「水は100度で沸騰する」とか「光は音よりも速く伝わる」などの物理法則を習ったとか教わった、とかなどと場合は、習った時点が過去であっても、従属節の時制は現在形である。
これに準じてか、歴史的事実を習ったり知ったりした場合などは、その事実を習ったりした時点が過去であっても、従属節をけっして過去完了形にせず(大過去にせず)、従属節は単なる過去形にする。
また、「彼は毎日散歩をする」とか「彼は毎日ジョギングをする」など、現在も通用している習慣を表す場合、従属節を過去にせず現在形にするのが普通。
ただし、習慣については、必ずしも従属節を必ず現在形にしないといけないわけではなく、惰性的に主節が過去形なら従属節もひきづられて過去形にすることも実際にはよくあるのが現実である(ロイヤル英文法)
ただし、習慣の内容の従属節を過去形にした場合、果たして現在もその習慣が続いているか分からない、という解釈をされるおそれがある。なので高校生向けの英文法参考書などでは、習慣については時制の一致の例外として現在形にするという教育が好まれている。
仮定法の場合も、時制の一致の例外である。
なお、実現しなかった願望を表す意味での仮定法は基本、仮定法過去または仮定法過去完了のどちらか片方である。
これとは別に「仮定法現在」というのがあるが、願望の表現ではなく、かつては条件文などで仮定法現在が使われていた歴史もあったが、しかし古風な表現方法であり、なので21世紀ではあまり使われない。古風な文体を意図的に書く場合などで、仮定法現在を用いる場合もある。
==== 未来 ====
未来の出来事であっても、交通機関の時刻表にもとづく出来事や、カレンダーにもとづく行事などは、確定的な未来であるとして、動詞は現在形で表す。
The flight leaves at 10:30. 「その飛行機は10時30分に出発する。」
なお、「飛行機」はであってもいい(青チャート)。
The plane leaves at 10:30. 「その飛行機は10時30分に出発する。」
ほか、現在進行形で、比較的近い、自身などの予定を表せる。
I'm leaving for Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
I'm visiting Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
上述の現在進行形による予定の表現には、現在その準備や手配を具体的に整えているという含みもある。
be about to ~ 「まさに~が始まろうとしている」
これとほとんど同じ意味で、
be on the point of ~ing
中学でも習ったように、
be going to ~(不定詞)
「~するつもりだ」で、あらかじめ考えていた未来の予定・景気悪を表すのが(インスパイア、青チャート)、通常である。
だが例外的に、「行く予定である」を
be going to go というのも、口調が悪いと考える人もいて、この場合は to go が省略されることもある(ロイヤル、インスパイア)。
be going on a picnic 「ピクニックに行くつもりだ」※ インスパイア
ほか、「来るつもり」 going to come の代わりに「coming」と言う場合もある(※ インスパイア)。
なお、will は、その場で考えた意志にもとづく未来の予想に使う。
たとえば、家族に「冷蔵庫に牛乳がないよ」とか「時計が壊れた」とか言われて、その返事として下記、
I'll get a new one today. 「それ今日、買ってくるわ。」 ※ 牛乳がないことに、家族に言われて初めて気づいた
I'm going to get a new one. 「それなら、今日買うつもりだよ。」 ※ 牛乳がなくなることを事前に予想していたり既に知っていたりして、購入計画をすでに立ててあった
というニュアンスの違いがある(青チャート、インスパイア)。
そのほか、「be to 動詞の原形」つまり 「be to不定詞」で、公的な予定を表す。
== 現在 ==
=== 一般的事実 ===
The earth goes around the sun. 「地球は太陽のまわりを回っている。」
のように、時間の経過により変化しない真理・一般的事実は、現在形であらわす(ジーニアス、エバーグリーン)。
なお、インスパイアでは、
The moon goes around the earth. 「月は地球のまわりを回っている。」
である。
ほか、
Water consists of hydrogen and oxygen. 「水は水素と酸素から成る。」※エバーグリーン、ロイヤル
=== ことわざ ===
ほか、ことわざも現在形が普通。
All roads lead to Rome. 「すべての道はローマに通ず」※ ジーニアス
Practice makes perfect. 「習うより慣れろ」 ※インスパイア
The earky bird catches the worm. 「早起きの鳥は虫を捕らえる。」(「早起きは三文の得」に相当)※青チャート
なお、「ローマは一日にしてならず」は過去形。
Rome was not built in a day. 「ローマは一日にしてならず」※ インスパイア
=== スポーツ実況など ===
John pass the ball to Mike. He kicks to the goal. 「ジョンがボールをマイクにパス。マイク、ゴールへシュート。」
※ 青チャート、インスパイア。
なお、実況放送では、進行の順番どおりに説明していくのが普通(インスパイア)。
=== 歴史的現在 ===
「歴史的現在」と言い、小説などで、過去の出来事でも、まるで目の前で起きているかのように、現在形で表す表現技法がある。(※ 青チャート、インスパイア。)
そのほか、古人の言葉を引用するとき、「~は・・・と言っている」と現在時制 says を用いることがある。過去時制でも良い(インスパイア)。
== 進行形 ==
be living は、一時的に住んでいる場合にだけ使う(エバーグリーン、インスパイア、ジーニアス)。
He is living in Tokyo. 「彼は東京に一時的に住んでいる。」
このように、一時性を強調するために進行形が使われる場合もある。
他の場合としては、推移中の現象を表すのに進行形が使われる場合もある。
たとえば be resembling は、進行中の「似てきている」という場合にだけ使う。
He is resembling his father more and more. 「彼はどんどん父親に似てきている。」
なお、
He resembles his mother.「彼は母に似ている。」
である。この母に似ているの文章を進行形にしたらダメ(青チャート)。なぜなら resemble の場合に進行形は、(時間の経過とともに)「どんどん似てきている」という推移を表す場合にしか使えないからである。
resemble は「似ている」という状態を表すので、だから resemble は「状態動詞」というものに分類されるのが一般的。
be動詞 resemble などが状態動詞である。
だが、青チャートは「状態動詞」の用語を採用していない。べつにこの用語がなくても説明できるので、読者はまあ頭の片隅にしまっておけばいい。
どの単語が状態動詞なのかも、参考書によって微妙に違う。
とりあえず、青チャートいわく、「物事の構成や関係を表す動詞」は普通、進行形にならない場合が多いとのことであり、具体的には
belong to (所属している)、 resemble (似ている)、differ (異なっている)、depend on (~に依存している)、consist of (~から成り立っている)、contain (~を含んでいる)、
などが、「原則として進行形にならない」とのこと(青チャート)。インスパイアにも、「状態や物事の構成、関係を表す動詞は進行形にならない」とあり、belong, consist, doffer, resemble を例にあげている。
「状態動詞」の説明の例として「状態を表す動詞」だと説明するのは、同義反復であり頭が悪そうである。それと比べると、青チャートの説明は優れている。
動詞 have について、「持つ」という動作の意味では「動作動詞」という分類である。一方、「持っている」という意味でなら have は「状態動詞」である。このように、同じ単語でも、どの意味で考えるかによって動作動詞なのか状態動詞なのかが異なる。
:※ 受験レベルでは、特にどの単語が動作動詞だったか等を覚える必要は無いだろう。
wear が参考書のよくある例(ジーニアス、ブレイクスルー)。
He always(またはusualy) wears a red seater. 「彼はいつも(または「よく」)赤いセーターを着ている。」
He is wearing a red seater. 「彼は赤いセーターを着ているところだ。」
知覚を表す see(見える) , hear(聞こえる), smell(においがする) ,taste (味がする),などは、ふつう、現在形である。
なにかが「現在、見えている最中である」ことを言いたい場合、seeではなく、looking や watching を使う(青チャート、エバーグリーンなど)。
なお、see には「会う」の意味もあり、会っている最中なら進行形になる場合もある(ジーニアス)。
「聞こえている最中である」場合なら、hear ではなく、listening を使う(エバ)。
smellを進行形にすると「においをかいでいる」という、やや別の意味の動詞になる(ブレイクスルー)。「においがしている」(×)というわけではない。
be tasting だと「味見をする」ときに使われる(青チャート)。このように進行形だと意味が違う場合がある。
そのほか、心や感情などをあらわす like, love ,hate, want, hope,forget , , などいくつかの動詞は、進行形にならない(ジーニアス、エバ)。
ただし、普通は進行形にしない動詞でも、例外的に一時的な動作や一時的な状態であることなどを強調したい場合、つまり一時性を強調したい場合には、進行形にすることもある(インスパイア)。
また、単語のスペルは同じでも、違う複数の意味をもつ場合があり、そのような場合に意味によっては進行形にすべきかどうかが、それぞれ違っていることもある(インスパイア)。
ほか、ジーニアスいわく「 I'm just Loving it. 」「好きでたまらない」のように、本来なら進行形にしないloveでも強調のために進行形にすることもあるのが実際とのこと(ジーニアス)。ただし、他の参考書では記述が見つからない。
a21uvm2fqm2q8sloxggugac2tk05xun
205832
205793
2022-07-25T07:48:33Z
すじにくシチュー
12058
/* 進行形 */
wikitext
text/x-wiki
=== 時制の一致と話法 ===
==== 時制の一致 ====
===== 時制の一致の原則 =====
ジーニアス、ロイヤル英文法にある典型的な例文だが、
「私は、彼が忙しいと思う」 I think that he is busy.
「私は、彼が忙しいと思った」 I thought that he was busy.
これを分析しよう。主節が「思った」と過去形になると、英語では、従属節の意味が「忙しい」と現在形であっても、主節にあわせて he was busy のように動詞が過去形になります。このような現象を「時制の一致」(じせいのいっち)と言います。
時制の一致が起きるのは、主節が過去形または過去完了形の場合だけである。なお、過去完了形については高校で習う。
つまり、現在形・現在進行形および未来時制・未来完了形では、時制の一致は起きない。
なお、過去から見た過去を言い表す場合は、従属節は過去形のままかあるいは過去完了(大過去)になる。参考書ではいちいち分析しないが、「時制の一致」の観点からも、「大過去」を考えることができる。
従属節が未来系であっても、主節が過去形でありさえすれば、時制の一致は起きる。たとえば例文、
「彼が~するだろうと思う」 I think he will ~.
「彼が遅れるだろうと思った。」 I thought he would ~.
である。
===== 時制の一致の例外 =====
従属節で「水は100度で沸騰する」とか「光は音よりも速く伝わる」などの物理法則を習ったとか教わった、とかなどと場合は、習った時点が過去であっても、従属節の時制は現在形である。
これに準じてか、歴史的事実を習ったり知ったりした場合などは、その事実を習ったりした時点が過去であっても、従属節をけっして過去完了形にせず(大過去にせず)、従属節は単なる過去形にする。
また、「彼は毎日散歩をする」とか「彼は毎日ジョギングをする」など、現在も通用している習慣を表す場合、従属節を過去にせず現在形にするのが普通。
ただし、習慣については、必ずしも従属節を必ず現在形にしないといけないわけではなく、惰性的に主節が過去形なら従属節もひきづられて過去形にすることも実際にはよくあるのが現実である(ロイヤル英文法)
ただし、習慣の内容の従属節を過去形にした場合、果たして現在もその習慣が続いているか分からない、という解釈をされるおそれがある。なので高校生向けの英文法参考書などでは、習慣については時制の一致の例外として現在形にするという教育が好まれている。
仮定法の場合も、時制の一致の例外である。
なお、実現しなかった願望を表す意味での仮定法は基本、仮定法過去または仮定法過去完了のどちらか片方である。
これとは別に「仮定法現在」というのがあるが、願望の表現ではなく、かつては条件文などで仮定法現在が使われていた歴史もあったが、しかし古風な表現方法であり、なので21世紀ではあまり使われない。古風な文体を意図的に書く場合などで、仮定法現在を用いる場合もある。
==== 未来 ====
未来の出来事であっても、交通機関の時刻表にもとづく出来事や、カレンダーにもとづく行事などは、確定的な未来であるとして、動詞は現在形で表す。
The flight leaves at 10:30. 「その飛行機は10時30分に出発する。」
なお、「飛行機」はであってもいい(青チャート)。
The plane leaves at 10:30. 「その飛行機は10時30分に出発する。」
ほか、現在進行形で、比較的近い、自身などの予定を表せる。
I'm leaving for Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
I'm visiting Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
上述の現在進行形による予定の表現には、現在その準備や手配を具体的に整えているという含みもある。
be about to ~ 「まさに~が始まろうとしている」
これとほとんど同じ意味で、
be on the point of ~ing
中学でも習ったように、
be going to ~(不定詞)
「~するつもりだ」で、あらかじめ考えていた未来の予定・景気悪を表すのが(インスパイア、青チャート)、通常である。
だが例外的に、「行く予定である」を
be going to go というのも、口調が悪いと考える人もいて、この場合は to go が省略されることもある(ロイヤル、インスパイア)。
be going on a picnic 「ピクニックに行くつもりだ」※ インスパイア
ほか、「来るつもり」 going to come の代わりに「coming」と言う場合もある(※ インスパイア)。
なお、will は、その場で考えた意志にもとづく未来の予想に使う。
たとえば、家族に「冷蔵庫に牛乳がないよ」とか「時計が壊れた」とか言われて、その返事として下記、
I'll get a new one today. 「それ今日、買ってくるわ。」 ※ 牛乳がないことに、家族に言われて初めて気づいた
I'm going to get a new one. 「それなら、今日買うつもりだよ。」 ※ 牛乳がなくなることを事前に予想していたり既に知っていたりして、購入計画をすでに立ててあった
というニュアンスの違いがある(青チャート、インスパイア)。
そのほか、「be to 動詞の原形」つまり 「be to不定詞」で、公的な予定を表す。
== 現在 ==
=== 一般的事実 ===
The earth goes around the sun. 「地球は太陽のまわりを回っている。」
のように、時間の経過により変化しない真理・一般的事実は、現在形であらわす(ジーニアス、エバーグリーン)。
なお、インスパイアでは、
The moon goes around the earth. 「月は地球のまわりを回っている。」
である。
ほか、
Water consists of hydrogen and oxygen. 「水は水素と酸素から成る。」※エバーグリーン、ロイヤル
=== ことわざ ===
ほか、ことわざも現在形が普通。
All roads lead to Rome. 「すべての道はローマに通ず」※ ジーニアス
Practice makes perfect. 「習うより慣れろ」 ※インスパイア
The earky bird catches the worm. 「早起きの鳥は虫を捕らえる。」(「早起きは三文の得」に相当)※青チャート
なお、「ローマは一日にしてならず」は過去形。
Rome was not built in a day. 「ローマは一日にしてならず」※ インスパイア
=== スポーツ実況など ===
John pass the ball to Mike. He kicks to the goal. 「ジョンがボールをマイクにパス。マイク、ゴールへシュート。」
※ 青チャート、インスパイア。
なお、実況放送では、進行の順番どおりに説明していくのが普通(インスパイア)。
=== 歴史的現在 ===
「歴史的現在」と言い、小説などで、過去の出来事でも、まるで目の前で起きているかのように、現在形で表す表現技法がある。(※ 青チャート、インスパイア。)
そのほか、古人の言葉を引用するとき、「~は・・・と言っている」と現在時制 says を用いることがある。過去時制でも良い(インスパイア)。
== 進行形 ==
be living は、一時的に住んでいる場合にだけ使う(エバーグリーン、インスパイア、ジーニアス)。
He is living in Tokyo. 「彼は東京に一時的に住んでいる。」
このように、一時性を強調するために進行形が使われる場合もある。
なお、完了形で He has lived in Tokyo for ten years. 「彼は東京に10年間住んでいる」のように言うのは構わないし、完了進行形でも He has been living in Tokyo for ten years. とも言える(インスパイア)。
下記の話は、完了形でない通常の現在形での進行形(つまり単なる現在進行形)のはなしです。
他の場合としては、推移中の現象を表すのに進行形が使われる場合もある。
たとえば be resembling は、進行中の「似てきている」という場合にだけ使う。
He is resembling his father more and more. 「彼はどんどん父親に似てきている。」
なお、
He resembles his mother.「彼は母に似ている。」
である。この母に似ているの文章を進行形にしたらダメ(青チャート)。なぜなら resemble の場合に進行形は、(時間の経過とともに)「どんどん似てきている」という推移を表す場合にしか使えないからである。
resemble は「似ている」という状態を表すので、だから resemble は「状態動詞」というものに分類されるのが一般的。
be動詞 resemble などが状態動詞である。
だが、青チャートは「状態動詞」の用語を採用していない。べつにこの用語がなくても説明できるので、読者はまあ頭の片隅にしまっておけばいい。
どの単語が状態動詞なのかも、参考書によって微妙に違う。
とりあえず、青チャートいわく、「物事の構成や関係を表す動詞」は普通、進行形にならない場合が多いとのことであり、具体的には
belong to (所属している)、 resemble (似ている)、differ (異なっている)、depend on (~に依存している)、consist of (~から成り立っている)、contain (~を含んでいる)、
などが、「原則として進行形にならない」とのこと(青チャート)。インスパイアにも、「状態や物事の構成、関係を表す動詞は進行形にならない」とあり、belong, consist, deffer, resemble を例にあげている。
「状態動詞」の説明の例として「状態を表す動詞」だと説明するのは、同義反復であり頭が悪そうである。それと比べると、青チャートの説明は優れている。
動詞 have について、「持つ」という動作の意味では「動作動詞」という分類である。一方、「持っている」という意味でなら have は「状態動詞」である。このように、同じ単語でも、どの意味で考えるかによって動作動詞なのか状態動詞なのかが異なる。
:※ 受験レベルでは、特にどの単語が動作動詞だったか等を覚える必要は無いだろう。
wear が参考書のよくある例(ジーニアス、ブレイクスルー)。
He always(またはusualy) wears a red sweater. 「彼はいつも(または「よく」)赤いセーターを着ている。」
He is wearing a red sweater. 「彼は赤いセーターを着ているところだ。」
知覚を表す see(見える) , hear(聞こえる), smell(においがする) ,taste (味がする),などは、ふつう、現在形である。
なにかが「現在、見えている最中である」ことを言いたい場合、seeではなく、looking や watching を使う(青チャート、エバーグリーンなど)。
なお、see には「会う」の意味もあり、会っている最中なら進行形になる場合もある(ジーニアス)。
「聞こえている最中である」場合なら、hear ではなく、listening を使う(エバ)。
smellを進行形にすると「においをかいでいる」という、やや別の意味の動詞になる(ブレイクスルー)。「においがしている」(×)というわけではない。
be tasting だと「味見をする」ときに使われる(青チャート)。このように進行形だと意味が違う場合がある。
そのほか、心や感情などをあらわす like, love ,hate, want, hope,forget , , などいくつかの動詞は、進行形にならない(ジーニアス、エバ)。
ただし、普通は進行形にしない動詞でも、例外的に一時的な動作や一時的な状態であることなどを強調したい場合、つまり一時性を強調したい場合には、進行形にすることもある(インスパイア)。
また、単語のスペルは同じでも、違う複数の意味をもつ場合があり、そのような場合に意味によっては進行形にすべきかどうかが、それぞれ違っていることもある(インスパイア)。
ほか、ジーニアスいわく「 I'm just Loving it. 」「好きでたまらない」のように、本来なら進行形にしないloveでも強調のために進行形にすることもあるのが実際とのこと(ジーニアス)。ただし、他の参考書では記述が見つからない。
== 現在完了進行形 ==
進行形でない単なる現在完了形には、状態の継続の用法がある。
一方、動作の継続については、現在完了進行形で言うことが多い。
I've been waiting here for an hour. 「私はここで一時間、待ち続けている。」
How long have you been waiting for the train? 「どれくらい電車を待っているのですか。」※ インスパイア、エバーグリーン
He has been running for an hour. 「彼は一時間ずっと、ランニングし続けている」
※ ジーニアス、エバーグリーンなど
なお、「He has been running for an hour.」 は、現時点でランニングが終了しても構わない(ブレイクスルー、インスパイア)。 running ではなく jogging の場合もある(ジーニアス、ブレイクスルー)。
He has been jogging for an hour. 「彼は一時間ずっと、ジョギングし続けている」
ほか参考書では、天候も、現在完了進行形でよく言われる例文が多い。
It has been raining for days. 「何日も雨が降り続いている。」 ※ ジーニアス、ブレイクスルー
It has been raining all day. 「1日中雨が降り続いている。」 ※ インスパイア。 なお「1日中」の1はインスパイアでは算用数字。
なお、完了形で He has lived in Tokyo for ten years. 「彼は東京に10年間住んでいる」のように言うのは構わないし、完了進行形でも He has been living in Tokyo for ten years. とも言える(インスパイア)。
gpmrjrsfmdw1gsmcittr32dbj0igbiq
205833
205832
2022-07-25T07:49:01Z
すじにくシチュー
12058
/* 現在完了進行形 */
wikitext
text/x-wiki
=== 時制の一致と話法 ===
==== 時制の一致 ====
===== 時制の一致の原則 =====
ジーニアス、ロイヤル英文法にある典型的な例文だが、
「私は、彼が忙しいと思う」 I think that he is busy.
「私は、彼が忙しいと思った」 I thought that he was busy.
これを分析しよう。主節が「思った」と過去形になると、英語では、従属節の意味が「忙しい」と現在形であっても、主節にあわせて he was busy のように動詞が過去形になります。このような現象を「時制の一致」(じせいのいっち)と言います。
時制の一致が起きるのは、主節が過去形または過去完了形の場合だけである。なお、過去完了形については高校で習う。
つまり、現在形・現在進行形および未来時制・未来完了形では、時制の一致は起きない。
なお、過去から見た過去を言い表す場合は、従属節は過去形のままかあるいは過去完了(大過去)になる。参考書ではいちいち分析しないが、「時制の一致」の観点からも、「大過去」を考えることができる。
従属節が未来系であっても、主節が過去形でありさえすれば、時制の一致は起きる。たとえば例文、
「彼が~するだろうと思う」 I think he will ~.
「彼が遅れるだろうと思った。」 I thought he would ~.
である。
===== 時制の一致の例外 =====
従属節で「水は100度で沸騰する」とか「光は音よりも速く伝わる」などの物理法則を習ったとか教わった、とかなどと場合は、習った時点が過去であっても、従属節の時制は現在形である。
これに準じてか、歴史的事実を習ったり知ったりした場合などは、その事実を習ったりした時点が過去であっても、従属節をけっして過去完了形にせず(大過去にせず)、従属節は単なる過去形にする。
また、「彼は毎日散歩をする」とか「彼は毎日ジョギングをする」など、現在も通用している習慣を表す場合、従属節を過去にせず現在形にするのが普通。
ただし、習慣については、必ずしも従属節を必ず現在形にしないといけないわけではなく、惰性的に主節が過去形なら従属節もひきづられて過去形にすることも実際にはよくあるのが現実である(ロイヤル英文法)
ただし、習慣の内容の従属節を過去形にした場合、果たして現在もその習慣が続いているか分からない、という解釈をされるおそれがある。なので高校生向けの英文法参考書などでは、習慣については時制の一致の例外として現在形にするという教育が好まれている。
仮定法の場合も、時制の一致の例外である。
なお、実現しなかった願望を表す意味での仮定法は基本、仮定法過去または仮定法過去完了のどちらか片方である。
これとは別に「仮定法現在」というのがあるが、願望の表現ではなく、かつては条件文などで仮定法現在が使われていた歴史もあったが、しかし古風な表現方法であり、なので21世紀ではあまり使われない。古風な文体を意図的に書く場合などで、仮定法現在を用いる場合もある。
==== 未来 ====
未来の出来事であっても、交通機関の時刻表にもとづく出来事や、カレンダーにもとづく行事などは、確定的な未来であるとして、動詞は現在形で表す。
The flight leaves at 10:30. 「その飛行機は10時30分に出発する。」
なお、「飛行機」はであってもいい(青チャート)。
The plane leaves at 10:30. 「その飛行機は10時30分に出発する。」
ほか、現在進行形で、比較的近い、自身などの予定を表せる。
I'm leaving for Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
I'm visiting Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
上述の現在進行形による予定の表現には、現在その準備や手配を具体的に整えているという含みもある。
be about to ~ 「まさに~が始まろうとしている」
これとほとんど同じ意味で、
be on the point of ~ing
中学でも習ったように、
be going to ~(不定詞)
「~するつもりだ」で、あらかじめ考えていた未来の予定・景気悪を表すのが(インスパイア、青チャート)、通常である。
だが例外的に、「行く予定である」を
be going to go というのも、口調が悪いと考える人もいて、この場合は to go が省略されることもある(ロイヤル、インスパイア)。
be going on a picnic 「ピクニックに行くつもりだ」※ インスパイア
ほか、「来るつもり」 going to come の代わりに「coming」と言う場合もある(※ インスパイア)。
なお、will は、その場で考えた意志にもとづく未来の予想に使う。
たとえば、家族に「冷蔵庫に牛乳がないよ」とか「時計が壊れた」とか言われて、その返事として下記、
I'll get a new one today. 「それ今日、買ってくるわ。」 ※ 牛乳がないことに、家族に言われて初めて気づいた
I'm going to get a new one. 「それなら、今日買うつもりだよ。」 ※ 牛乳がなくなることを事前に予想していたり既に知っていたりして、購入計画をすでに立ててあった
というニュアンスの違いがある(青チャート、インスパイア)。
そのほか、「be to 動詞の原形」つまり 「be to不定詞」で、公的な予定を表す。
== 現在 ==
=== 一般的事実 ===
The earth goes around the sun. 「地球は太陽のまわりを回っている。」
のように、時間の経過により変化しない真理・一般的事実は、現在形であらわす(ジーニアス、エバーグリーン)。
なお、インスパイアでは、
The moon goes around the earth. 「月は地球のまわりを回っている。」
である。
ほか、
Water consists of hydrogen and oxygen. 「水は水素と酸素から成る。」※エバーグリーン、ロイヤル
=== ことわざ ===
ほか、ことわざも現在形が普通。
All roads lead to Rome. 「すべての道はローマに通ず」※ ジーニアス
Practice makes perfect. 「習うより慣れろ」 ※インスパイア
The earky bird catches the worm. 「早起きの鳥は虫を捕らえる。」(「早起きは三文の得」に相当)※青チャート
なお、「ローマは一日にしてならず」は過去形。
Rome was not built in a day. 「ローマは一日にしてならず」※ インスパイア
=== スポーツ実況など ===
John pass the ball to Mike. He kicks to the goal. 「ジョンがボールをマイクにパス。マイク、ゴールへシュート。」
※ 青チャート、インスパイア。
なお、実況放送では、進行の順番どおりに説明していくのが普通(インスパイア)。
=== 歴史的現在 ===
「歴史的現在」と言い、小説などで、過去の出来事でも、まるで目の前で起きているかのように、現在形で表す表現技法がある。(※ 青チャート、インスパイア。)
そのほか、古人の言葉を引用するとき、「~は・・・と言っている」と現在時制 says を用いることがある。過去時制でも良い(インスパイア)。
== 進行形 ==
be living は、一時的に住んでいる場合にだけ使う(エバーグリーン、インスパイア、ジーニアス)。
He is living in Tokyo. 「彼は東京に一時的に住んでいる。」
このように、一時性を強調するために進行形が使われる場合もある。
なお、完了形で He has lived in Tokyo for ten years. 「彼は東京に10年間住んでいる」のように言うのは構わないし、完了進行形でも He has been living in Tokyo for ten years. とも言える(インスパイア)。
下記の話は、完了形でない通常の現在形での進行形(つまり単なる現在進行形)のはなしです。
他の場合としては、推移中の現象を表すのに進行形が使われる場合もある。
たとえば be resembling は、進行中の「似てきている」という場合にだけ使う。
He is resembling his father more and more. 「彼はどんどん父親に似てきている。」
なお、
He resembles his mother.「彼は母に似ている。」
である。この母に似ているの文章を進行形にしたらダメ(青チャート)。なぜなら resemble の場合に進行形は、(時間の経過とともに)「どんどん似てきている」という推移を表す場合にしか使えないからである。
resemble は「似ている」という状態を表すので、だから resemble は「状態動詞」というものに分類されるのが一般的。
be動詞 resemble などが状態動詞である。
だが、青チャートは「状態動詞」の用語を採用していない。べつにこの用語がなくても説明できるので、読者はまあ頭の片隅にしまっておけばいい。
どの単語が状態動詞なのかも、参考書によって微妙に違う。
とりあえず、青チャートいわく、「物事の構成や関係を表す動詞」は普通、進行形にならない場合が多いとのことであり、具体的には
belong to (所属している)、 resemble (似ている)、differ (異なっている)、depend on (~に依存している)、consist of (~から成り立っている)、contain (~を含んでいる)、
などが、「原則として進行形にならない」とのこと(青チャート)。インスパイアにも、「状態や物事の構成、関係を表す動詞は進行形にならない」とあり、belong, consist, deffer, resemble を例にあげている。
「状態動詞」の説明の例として「状態を表す動詞」だと説明するのは、同義反復であり頭が悪そうである。それと比べると、青チャートの説明は優れている。
動詞 have について、「持つ」という動作の意味では「動作動詞」という分類である。一方、「持っている」という意味でなら have は「状態動詞」である。このように、同じ単語でも、どの意味で考えるかによって動作動詞なのか状態動詞なのかが異なる。
:※ 受験レベルでは、特にどの単語が動作動詞だったか等を覚える必要は無いだろう。
wear が参考書のよくある例(ジーニアス、ブレイクスルー)。
He always(またはusualy) wears a red sweater. 「彼はいつも(または「よく」)赤いセーターを着ている。」
He is wearing a red sweater. 「彼は赤いセーターを着ているところだ。」
知覚を表す see(見える) , hear(聞こえる), smell(においがする) ,taste (味がする),などは、ふつう、現在形である。
なにかが「現在、見えている最中である」ことを言いたい場合、seeではなく、looking や watching を使う(青チャート、エバーグリーンなど)。
なお、see には「会う」の意味もあり、会っている最中なら進行形になる場合もある(ジーニアス)。
「聞こえている最中である」場合なら、hear ではなく、listening を使う(エバ)。
smellを進行形にすると「においをかいでいる」という、やや別の意味の動詞になる(ブレイクスルー)。「においがしている」(×)というわけではない。
be tasting だと「味見をする」ときに使われる(青チャート)。このように進行形だと意味が違う場合がある。
そのほか、心や感情などをあらわす like, love ,hate, want, hope,forget , , などいくつかの動詞は、進行形にならない(ジーニアス、エバ)。
ただし、普通は進行形にしない動詞でも、例外的に一時的な動作や一時的な状態であることなどを強調したい場合、つまり一時性を強調したい場合には、進行形にすることもある(インスパイア)。
また、単語のスペルは同じでも、違う複数の意味をもつ場合があり、そのような場合に意味によっては進行形にすべきかどうかが、それぞれ違っていることもある(インスパイア)。
ほか、ジーニアスいわく「 I'm just Loving it. 」「好きでたまらない」のように、本来なら進行形にしないloveでも強調のために進行形にすることもあるのが実際とのこと(ジーニアス)。ただし、他の参考書では記述が見つからない。
== 現在完了進行形 ==
進行形でない単なる現在完了形には、'''状態'''の'''継続'''の用法がある。
一方、動作の継続については、現在完了進行形で言うことが多い。
I've been waiting here for an hour. 「私はここで一時間、待ち続けている。」
How long have you been waiting for the train? 「どれくらい電車を待っているのですか。」※ インスパイア、エバーグリーン
He has been running for an hour. 「彼は一時間ずっと、ランニングし続けている」
※ ジーニアス、エバーグリーンなど
なお、「He has been running for an hour.」 は、現時点でランニングが終了しても構わない(ブレイクスルー、インスパイア)。 running ではなく jogging の場合もある(ジーニアス、ブレイクスルー)。
He has been jogging for an hour. 「彼は一時間ずっと、ジョギングし続けている」
ほか参考書では、天候も、現在完了進行形でよく言われる例文が多い。
It has been raining for days. 「何日も雨が降り続いている。」 ※ ジーニアス、ブレイクスルー
It has been raining all day. 「1日中雨が降り続いている。」 ※ インスパイア。 なお「1日中」の1はインスパイアでは算用数字。
なお、完了形で He has lived in Tokyo for ten years. 「彼は東京に10年間住んでいる」のように言うのは構わないし、完了進行形でも He has been living in Tokyo for ten years. とも言える(インスパイア)。
qq891xmpd4jiizovhuz4dq3pkx1miri
205835
205833
2022-07-25T08:02:30Z
すじにくシチュー
12058
/* 現在完了進行形 */
wikitext
text/x-wiki
=== 時制の一致と話法 ===
==== 時制の一致 ====
===== 時制の一致の原則 =====
ジーニアス、ロイヤル英文法にある典型的な例文だが、
「私は、彼が忙しいと思う」 I think that he is busy.
「私は、彼が忙しいと思った」 I thought that he was busy.
これを分析しよう。主節が「思った」と過去形になると、英語では、従属節の意味が「忙しい」と現在形であっても、主節にあわせて he was busy のように動詞が過去形になります。このような現象を「時制の一致」(じせいのいっち)と言います。
時制の一致が起きるのは、主節が過去形または過去完了形の場合だけである。なお、過去完了形については高校で習う。
つまり、現在形・現在進行形および未来時制・未来完了形では、時制の一致は起きない。
なお、過去から見た過去を言い表す場合は、従属節は過去形のままかあるいは過去完了(大過去)になる。参考書ではいちいち分析しないが、「時制の一致」の観点からも、「大過去」を考えることができる。
従属節が未来系であっても、主節が過去形でありさえすれば、時制の一致は起きる。たとえば例文、
「彼が~するだろうと思う」 I think he will ~.
「彼が遅れるだろうと思った。」 I thought he would ~.
である。
===== 時制の一致の例外 =====
従属節で「水は100度で沸騰する」とか「光は音よりも速く伝わる」などの物理法則を習ったとか教わった、とかなどと場合は、習った時点が過去であっても、従属節の時制は現在形である。
これに準じてか、歴史的事実を習ったり知ったりした場合などは、その事実を習ったりした時点が過去であっても、従属節をけっして過去完了形にせず(大過去にせず)、従属節は単なる過去形にする。
また、「彼は毎日散歩をする」とか「彼は毎日ジョギングをする」など、現在も通用している習慣を表す場合、従属節を過去にせず現在形にするのが普通。
ただし、習慣については、必ずしも従属節を必ず現在形にしないといけないわけではなく、惰性的に主節が過去形なら従属節もひきづられて過去形にすることも実際にはよくあるのが現実である(ロイヤル英文法)
ただし、習慣の内容の従属節を過去形にした場合、果たして現在もその習慣が続いているか分からない、という解釈をされるおそれがある。なので高校生向けの英文法参考書などでは、習慣については時制の一致の例外として現在形にするという教育が好まれている。
仮定法の場合も、時制の一致の例外である。
なお、実現しなかった願望を表す意味での仮定法は基本、仮定法過去または仮定法過去完了のどちらか片方である。
これとは別に「仮定法現在」というのがあるが、願望の表現ではなく、かつては条件文などで仮定法現在が使われていた歴史もあったが、しかし古風な表現方法であり、なので21世紀ではあまり使われない。古風な文体を意図的に書く場合などで、仮定法現在を用いる場合もある。
==== 未来 ====
未来の出来事であっても、交通機関の時刻表にもとづく出来事や、カレンダーにもとづく行事などは、確定的な未来であるとして、動詞は現在形で表す。
The flight leaves at 10:30. 「その飛行機は10時30分に出発する。」
なお、「飛行機」はであってもいい(青チャート)。
The plane leaves at 10:30. 「その飛行機は10時30分に出発する。」
ほか、現在進行形で、比較的近い、自身などの予定を表せる。
I'm leaving for Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
I'm visiting Sapporo tomorrow. 「私は明日、札幌に行く予定です。」
上述の現在進行形による予定の表現には、現在その準備や手配を具体的に整えているという含みもある。
be about to ~ 「まさに~が始まろうとしている」
これとほとんど同じ意味で、
be on the point of ~ing
中学でも習ったように、
be going to ~(不定詞)
「~するつもりだ」で、あらかじめ考えていた未来の予定・景気悪を表すのが(インスパイア、青チャート)、通常である。
だが例外的に、「行く予定である」を
be going to go というのも、口調が悪いと考える人もいて、この場合は to go が省略されることもある(ロイヤル、インスパイア)。
be going on a picnic 「ピクニックに行くつもりだ」※ インスパイア
ほか、「来るつもり」 going to come の代わりに「coming」と言う場合もある(※ インスパイア)。
なお、will は、その場で考えた意志にもとづく未来の予想に使う。
たとえば、家族に「冷蔵庫に牛乳がないよ」とか「時計が壊れた」とか言われて、その返事として下記、
I'll get a new one today. 「それ今日、買ってくるわ。」 ※ 牛乳がないことに、家族に言われて初めて気づいた
I'm going to get a new one. 「それなら、今日買うつもりだよ。」 ※ 牛乳がなくなることを事前に予想していたり既に知っていたりして、購入計画をすでに立ててあった
というニュアンスの違いがある(青チャート、インスパイア)。
そのほか、「be to 動詞の原形」つまり 「be to不定詞」で、公的な予定を表す。
== 現在 ==
=== 一般的事実 ===
The earth goes around the sun. 「地球は太陽のまわりを回っている。」
のように、時間の経過により変化しない真理・一般的事実は、現在形であらわす(ジーニアス、エバーグリーン)。
なお、インスパイアでは、
The moon goes around the earth. 「月は地球のまわりを回っている。」
である。
ほか、
Water consists of hydrogen and oxygen. 「水は水素と酸素から成る。」※エバーグリーン、ロイヤル
=== ことわざ ===
ほか、ことわざも現在形が普通。
All roads lead to Rome. 「すべての道はローマに通ず」※ ジーニアス
Practice makes perfect. 「習うより慣れろ」 ※インスパイア
The earky bird catches the worm. 「早起きの鳥は虫を捕らえる。」(「早起きは三文の得」に相当)※青チャート
なお、「ローマは一日にしてならず」は過去形。
Rome was not built in a day. 「ローマは一日にしてならず」※ インスパイア
=== スポーツ実況など ===
John pass the ball to Mike. He kicks to the goal. 「ジョンがボールをマイクにパス。マイク、ゴールへシュート。」
※ 青チャート、インスパイア。
なお、実況放送では、進行の順番どおりに説明していくのが普通(インスパイア)。
=== 歴史的現在 ===
「歴史的現在」と言い、小説などで、過去の出来事でも、まるで目の前で起きているかのように、現在形で表す表現技法がある。(※ 青チャート、インスパイア。)
そのほか、古人の言葉を引用するとき、「~は・・・と言っている」と現在時制 says を用いることがある。過去時制でも良い(インスパイア)。
== 進行形 ==
be living は、一時的に住んでいる場合にだけ使う(エバーグリーン、インスパイア、ジーニアス)。
He is living in Tokyo. 「彼は東京に一時的に住んでいる。」
このように、一時性を強調するために進行形が使われる場合もある。
なお、完了形で He has lived in Tokyo for ten years. 「彼は東京に10年間住んでいる」のように言うのは構わないし、完了進行形でも He has been living in Tokyo for ten years. とも言える(インスパイア)。
下記の話は、完了形でない通常の現在形での進行形(つまり単なる現在進行形)のはなしです。
他の場合としては、推移中の現象を表すのに進行形が使われる場合もある。
たとえば be resembling は、進行中の「似てきている」という場合にだけ使う。
He is resembling his father more and more. 「彼はどんどん父親に似てきている。」
なお、
He resembles his mother.「彼は母に似ている。」
である。この母に似ているの文章を進行形にしたらダメ(青チャート)。なぜなら resemble の場合に進行形は、(時間の経過とともに)「どんどん似てきている」という推移を表す場合にしか使えないからである。
resemble は「似ている」という状態を表すので、だから resemble は「状態動詞」というものに分類されるのが一般的。
be動詞 resemble などが状態動詞である。
だが、青チャートは「状態動詞」の用語を採用していない。べつにこの用語がなくても説明できるので、読者はまあ頭の片隅にしまっておけばいい。
どの単語が状態動詞なのかも、参考書によって微妙に違う。
とりあえず、青チャートいわく、「物事の構成や関係を表す動詞」は普通、進行形にならない場合が多いとのことであり、具体的には
belong to (所属している)、 resemble (似ている)、differ (異なっている)、depend on (~に依存している)、consist of (~から成り立っている)、contain (~を含んでいる)、
などが、「原則として進行形にならない」とのこと(青チャート)。インスパイアにも、「状態や物事の構成、関係を表す動詞は進行形にならない」とあり、belong, consist, deffer, resemble を例にあげている。
「状態動詞」の説明の例として「状態を表す動詞」だと説明するのは、同義反復であり頭が悪そうである。それと比べると、青チャートの説明は優れている。
動詞 have について、「持つ」という動作の意味では「動作動詞」という分類である。一方、「持っている」という意味でなら have は「状態動詞」である。このように、同じ単語でも、どの意味で考えるかによって動作動詞なのか状態動詞なのかが異なる。
:※ 受験レベルでは、特にどの単語が動作動詞だったか等を覚える必要は無いだろう。
wear が参考書のよくある例(ジーニアス、ブレイクスルー)。
He always(またはusualy) wears a red sweater. 「彼はいつも(または「よく」)赤いセーターを着ている。」
He is wearing a red sweater. 「彼は赤いセーターを着ているところだ。」
知覚を表す see(見える) , hear(聞こえる), smell(においがする) ,taste (味がする),などは、ふつう、現在形である。
なにかが「現在、見えている最中である」ことを言いたい場合、seeではなく、looking や watching を使う(青チャート、エバーグリーンなど)。
なお、see には「会う」の意味もあり、会っている最中なら進行形になる場合もある(ジーニアス)。
「聞こえている最中である」場合なら、hear ではなく、listening を使う(エバ)。
smellを進行形にすると「においをかいでいる」という、やや別の意味の動詞になる(ブレイクスルー)。「においがしている」(×)というわけではない。
be tasting だと「味見をする」ときに使われる(青チャート)。このように進行形だと意味が違う場合がある。
そのほか、心や感情などをあらわす like, love ,hate, want, hope,forget , , などいくつかの動詞は、進行形にならない(ジーニアス、エバ)。
ただし、普通は進行形にしない動詞でも、例外的に一時的な動作や一時的な状態であることなどを強調したい場合、つまり一時性を強調したい場合には、進行形にすることもある(インスパイア)。
また、単語のスペルは同じでも、違う複数の意味をもつ場合があり、そのような場合に意味によっては進行形にすべきかどうかが、それぞれ違っていることもある(インスパイア)。
ほか、ジーニアスいわく「 I'm just Loving it. 」「好きでたまらない」のように、本来なら進行形にしないloveでも強調のために進行形にすることもあるのが実際とのこと(ジーニアス)。ただし、他の参考書では記述が見つからない。
== 現在完了進行形 ==
進行形でない単なる現在完了形には、'''状態'''の'''継続'''の用法がある。
一方、動作の継続については、現在完了進行形で言うことが多い。
I've been waiting here for an hour. 「私はここで一時間、待ち続けている。」
How long have you been waiting for the train? 「どれくらい電車を待っているのですか。」※ インスパイア、エバーグリーン
He has been running for an hour. 「彼は一時間ずっと、ランニングし続けている」
※ ジーニアス、エバーグリーンなど
なお、「He has been running for an hour.」 は、現時点でランニングが終了しても構わない(ブレイクスルー、インスパイア)。だからといって、必ずしも現在完了進行形では現時点でランニング終了とも限らないので(エバーグリーン)、断定しないように。直前までの動作が終了している場合と、まだ終了指定なお場合との、両方の場合がありうる(エバーグリーン)。
参考書によっては動詞が running ではなく jogging の場合もある(ジーニアス、ブレイクスルー)。
He has been jogging for an hour. 「彼は一時間ずっと、ジョギングし続けている」
ほか参考書では、天候も、現在完了進行形でよく言われる例文が多い。
It has been raining for days. 「何日も雨が降り続いている。」 ※ ジーニアス、ブレイクスルー
It has been raining all day. 「1日中雨が降り続いている。」 ※ インスパイア。 なお「1日中」の1はインスパイアでは算用数字。
なお、完了形で He has lived in Tokyo for ten years. 「彼は東京に10年間住んでいる」のように言うのは構わないし、完了進行形でも He has been living in Tokyo for ten years. とも言える(インスパイア)。
live の例でも分かるように、習慣を完了進行形で言っても構わない。
たとえばインスパイアでは「私たちは6年間ずっと英語を勉強しています」をhave been studying および have studied で説明している。
エバーグリーンでは、「私たちは5年間英語の勉強をしています」を
We have studied English for five years.
We have been studying English for five years.
で説明しており(インスパイアもほぼ同様の例文で five が six になっただけ)、エバーグリーンいわく(現在完了形と)「現在完了進行形との意味の違いは、たいがい、無視できるほどわずかである。とはいえ、長期に渡って安定した状態を表す場合には、現在完了形が好まれる。」とある。
ジーニアスでは「エリーは10歳の時から日記をつづけている。」を has been keeping a diary で説明している。
まさか英語以外のことを6年間勉強してこない事は常識的に考えらないし、常識的にエリーも日記以外の動作もしているのだろうから、つまり上記の例文は習慣の意味だろう(参考書では明言されていない)。
また、習慣の継続の意味では、別に完了進行形でも、単なる完了形でも、どちらでもいいことが、上記の例文から分かる(参考書では明言されていない)。
0akt26dc01y5110yivv2jqea050yqkv
Zig
0
35197
205788
205787
2022-07-24T12:25:44Z
Ef3
694
/* 値と型 */ clenup
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(しばしば互換性のない)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
===== コードの実行方法 =====
[TBD:]
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
===== build & exec =====
zig コマンドは、コッンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルのコンパイル(ソースコードの変更などの必要性があれば)とコンパイルの成果物の実行を行います。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクト作成する場合 =====
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレキトリー myproj を用意し、zig init-exe を実行します。
:<syntaxhighlight lang=console>
% cd myproj/
% zig init-exe
% % find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
[TODO:書くべき項目を並べてみましたが、例えば「値と型」を網羅的に書いていくと文章量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。]
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
:<syntaxhighlight lang=zig>
// @import は組込み関数です。
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型]
:<syntaxhighlight lang=zig>
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
<!-- リテラルの例、というか、@import("std").io.getStdOut().writer().print の例になっていますね。-->
ご覧のように、数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数は基数を、浮動小数点数は指数表現と少数表現があります。
@import("std").io.getStdOut().writer().printの、第一引数は書式化文字列、第二引数は値リストです。
書式化文字列は、通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、引数リストの値(を書式化した文字列)に置換わります。
一番素朴なプレスホルダーは {} で、引数の値の一般的な文字列表記に置き換ります(整数なら十進数表記、浮動小数点数なら指数表記)。
ところが、’c’ のような文字型を {} に適用すると文字コード化され整数と同じ十進数表記になってしまいます。そこで、文字型の場合は {c} と文字であることを明記すると文字表現となります。
また、文字列の間合いは {s} を明記しないと(バージョン0.8.0からは)エラーになります。
2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りのリストにします( これが、Zig の配列リテラルの表現で、{} の前の . (点)を忘れがち)。
基本的に、左から順にプレスホルダーにリストの値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
==== comptime ====
Zigでは、コンパイル時に式が既知かどうかという概念を重要視しています。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
ifrh0if8ewf0hpenlywwmzd1s7713q4
205789
205788
2022-07-24T12:34:24Z
Ef3
694
/* 基礎篇 */ Fix markup
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(しばしば互換性のない)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
===== コードの実行方法 =====
[TBD:]
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
===== build & exec =====
zig コマンドは、コッンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルのコンパイル(ソースコードの変更などの必要性があれば)とコンパイルの成果物の実行を行います。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクト作成する場合 =====
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレキトリー myproj を用意し、zig init-exe を実行します。
:<syntaxhighlight lang=console>
% cd myproj/
% zig init-exe
% % find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
<!-- TODO:書くべき項目を並べてみましたが、例えば「値と型」だけでも網羅的に書いていくとコンテンツの分量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。-->
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
;hello.zig:<syntaxhighlight lang=zig>
// hello.zig:
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型]
:<syntaxhighlight lang=zig highlight="9,10">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text highlight="7,8">
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
<!-- リテラルの例、というか、@import("std").io.getStdOut().writer().print の例になっていますね。-->
ご覧のように、数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数は基数を、浮動小数点数は指数表現と少数表現があります。
@import("std").io.getStdOut().writer().printの、第一引数は書式化文字列、第二引数は値リストです。
書式化文字列は、通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、引数リストの値(を書式化した文字列)に置換わります。
一番素朴なプレスホルダーは {} で、引数の値の一般的な文字列表記に置き換ります(整数なら十進数表記、浮動小数点数なら指数表記)。
ところが、’c’ のような文字型を {} に適用すると文字コード化され整数と同じ十進数表記になってしまいます。そこで、文字型の場合は {c} と文字であることを明記すると文字表現となります。
また、文字列の間合いは {s} を明記しないと(バージョン0.8.0からは)エラーになります。
2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りのリストにします( これが、Zig の配列リテラルの表現で、{} の前の . (点)を忘れがち)。
基本的に、左から順にプレスホルダーにリストの値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
==== comptime ====
Zigでは、コンパイル時に式が既知かどうかという概念を重要視しています。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
7zsqv7djdma0vvxbcart8c8j82xf571
205790
205789
2022-07-24T12:38:50Z
Ef3
694
Fix typo
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(互換性を失いがち)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
===== コードの実行方法 =====
[TBD:]
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
===== build & exec =====
zig コマンドは、コッンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルのコンパイル(ソースコードの変更などの必要性があれば)とコンパイルの成果物の実行を行います。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクト作成する場合 =====
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレクトリー myproj を用意し、zig init-exe を実行します。
:<syntaxhighlight lang=console>
% cd myproj/
% zig init-exe
% % find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
<!-- TODO:書くべき項目を並べてみましたが、例えば「値と型」だけでも網羅的に書いていくとコンテンツの分量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。-->
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
;hello.zig:<syntaxhighlight lang=zig>
// hello.zig:
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型]
:<syntaxhighlight lang=zig highlight="9,10">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text highlight="7,8">
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
<!-- リテラルの例、というか、@import("std").io.getStdOut().writer().print の例になっていますね。-->
ご覧のように、数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数は基数を、浮動小数点数は指数表現と少数表現があります。
@import("std").io.getStdOut().writer().printの、第一引数は書式化文字列、第二引数は値リストです。
書式化文字列は、通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、引数リストの値(を書式化した文字列)に置換わります。
一番素朴なプレスホルダーは {} で、引数の値の一般的な文字列表記に置き換ります(整数なら十進数表記、浮動小数点数なら指数表記)。
ところが、’c’ のような文字型を {} に適用すると文字コード化され整数と同じ十進数表記になってしまいます。そこで、文字型の場合は {c} と文字であることを明記すると文字表現となります。
また、文字列の間合いは {s} を明記しないと(バージョン0.8.0からは)エラーになります。
2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りのリストにします( これが、Zig の配列リテラルの表現で、{} の前の . (点)を忘れがち)。
基本的に、左から順にプレスホルダーにリストの値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
==== comptime ====
Zigでは、コンパイル時に式が既知かどうかという概念を重要視しています。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
ocjn5r7bch8pw89h7lmtk7akfnj7jqg
205791
205790
2022-07-24T12:49:09Z
Ef3
694
荒らし対応
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(互換性を失いがち)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
===== コードの実行方法 =====
[TBD:]
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
===== build & exec =====
zig コマンドは、コッンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルのコンパイル(ソースコードの変更などの必要性があれば)とコンパイルの成果物の実行を行います。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクト作成する場合 =====
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレクトリー myproj を用意し、zig init-exe を実行します。
:<syntaxhighlight lang=console>
% cd myproj/
% zig init-exe
% % find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
<!-- TODO:書くべき項目を並べてみましたが、例えば「値と型」だけでも網羅的に書いていくとコンテンツの分量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。-->
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
;hello.zig:<syntaxhighlight lang=zig>
// hello.zig:
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
4gusrarxu7m1i6w3n1ouihfzmx7ffh3
205792
205791
2022-07-24T12:52:06Z
Ef3
694
/* コードの実行方法 */ inadapté
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(互換性を失いがち)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
===== build & exec =====
zig コマンドは、コッンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルのコンパイル(ソースコードの変更などの必要性があれば)とコンパイルの成果物の実行を行います。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクト作成する場合 =====
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレクトリー myproj を用意し、zig init-exe を実行します。
:<syntaxhighlight lang=console>
% cd myproj/
% zig init-exe
% % find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
<!-- TODO:書くべき項目を並べてみましたが、例えば「値と型」だけでも網羅的に書いていくとコンテンツの分量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。-->
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
;hello.zig:<syntaxhighlight lang=zig>
// hello.zig:
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
s5slcdwqce01n9ce12wpv125yn48iag
205794
205792
2022-07-24T13:07:37Z
Ef3
694
/* プロジェクトの作成 */ s/プロジェクト作成する場合/プロジェクトの作成/;プログラミングの上で必須ではありませんが、プロジェクト単位でファイルやビルド手順を他からアイソレーションすることができ、zigコマンドにもそれを支援する機能があります。 プログラムの記述言語で、ビルドツールのレシピを書くことができるのは魅力的ですが、当の記述言語の習得中には有難みも半減なので、複数のソースに分割する規模になるまでは単に、zig ソースファイル で不都合はありません。
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(互換性を失いがち)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
===== build & exec =====
zig コマンドは、コッンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルのコンパイル(ソースコードの変更などの必要性があれば)とコンパイルの成果物の実行を行います。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクトの作成 =====
プログラミングの上で必須ではありませんが、プロジェクト単位でファイルやビルド手順を他からアイソレーションすることができ、zigコマンドにもそれを支援する機能があります。
プログラムの記述言語で、ビルドツールのレシピを書くことができるのは魅力的ですが、当の記述言語の習得中には有難みも半減なので、複数のソースに分割する規模になるまでは単に、zig ソースファイル で不都合はありません。
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレクトリー myproj を用意し、zig init-exe を実行します。
;myproj の雛型生成とスケルトンのままビルド(と実行):<syntaxhighlight lang=console>
% mkdir myproj/
% cd myproj/
% zig init-exe
% find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
<!-- TODO:書くべき項目を並べてみましたが、例えば「値と型」だけでも網羅的に書いていくとコンテンツの分量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。-->
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
;hello.zig:<syntaxhighlight lang=zig>
// hello.zig:
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
7r4dp3qqjpldgph1t771i6yqhdgua0s
205795
205794
2022-07-24T13:23:52Z
Ef3
694
/* build & exec */ zig コマンドは、コンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルの(ソースコードの変更やキャッシュ クリアーなど必要性があれば)コンパイルとコンパイルの成果物の実行を行います。これを「インタープリター風」と称することがありますが、二回目からはソースファイルを変更したりキャッシュをクリアーしない限りコンパイルのオーバーヘッドが不要で、キャッシュ内の実行形式が実行されるなど、ビルドツール/ビルドシステムとしての特徴が際立ち、逐次解釈的な要素は希薄(皆無)です<ref>crystal の <code>i/interactive</code> サブコマンドのように、真に対話的に実行する処理系も既にあるので、ビルドシステムの簡易呼出しとインタープリターを混同すべきではありません)</ref>。
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Zig (プログラミング言語)}}
本書は、[[w:Zig|Zig]]のチュートリアルです。
Zigは、堅牢で最適かつ再利用可能なソフトウェアを維持するための汎用プログラミング言語およびツールチェインです<ref>{{Cite web
|url=https://ziglang.org/
|title=Home ⚡ Zig Programming Language
|website=ziglang.org
|accessdate=2022-07-17
|cite=Zig is a general-purpose programming language and toolchain for maintaining '''robust''', '''optimal''' and '''reusable''' software.
}}</ref>。
Zigは、アンドリュー・ケリー( ''[https://andrewkelley.me/ Andrew Kelley]'' )によって設計され、汎用システムプログラミング言語で、静的で強い型付けで型推論とジェネリックプログラミングをサポートします。
== 概要 ==
Zigは、2016年2月に発表された比較的若いプログラミング言語で<ref>{{Cite web
|last1=Kelley
|first1=Andrew
|title=Introduction to the Zig Programming Language
|url=https://andrewkelley.me/post/intro-to-zig.html
|website=andrewkelley.me
|accessdate=2022-07-17
}}</ref>、2022年7月現在のバージョンは 0.9.1 で、'''''pre-release''''' と位置づけられています<ref>{{Cite web
|url=https://github.com/ziglang/zig/releases
|title=Releases · ziglang/zig
|website=github.com
|accessdate=2022-07-17
}}</ref>。このため [[W:Hello world|Hello world]] ですら、バージョン間で互換性がなくなることもあり、リリースバージョンまでは言語仕様やライブラリーおよびツールチェインの仕様が変更される可能性があります。
=== Hello world の変遷 ===
[https://ziglang.org/documentation/master/ Zig Language Reference]の、[[W:Hello world|Hello world]]の変遷(新しい順)。
;master@2022-07-17<ref>{{Cite web
|url=https://ziglang.org/documentation/master/#Hello-World
|title=Zig Documentation(master@2022-07-17)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.9.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.9.1/#Hello-World
|title=Zig Documentation(0.9.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.8.1に同じ
;0.8.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.8.1/#Hello-World
|title=Zig Documentation(0.8.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
</syntaxhighlight>
: <code>{}</code> ⇒ <code>{s}</code><ref>{{Cite web
|url=https://ziglang.org/download/0.8.0/release-notes.html#Formatted-Printing
|title=0.8.0 Release Notes
|website=ziglang.org
|accessdate=2022-07-17
|quote=Disable the special casing of {} for u8 slices/arrays. Unless {s} is specified the contents won't be treated as a string.
}}</ref>
;0.7.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.7.1/#Hello-World
|title=Zig Documentation(0.7.1)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: s/outStream/writer/
;0.6.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.6.0/#Hello-World
|title=Zig Documentation(0.6.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=3>
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
try stdout.print("Hello, {}!\n", .{"world"});
}
</syntaxhighlight>
: 初期化の初期値から <code>try</code> がなくなった。
;0.4.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.4.0/#Hello-World
|title=Zig Documentation(0.4.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.5.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.5.0/#Hello-World
|title=Zig Documentation(0.5.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig highlight=4>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
: <var>stdout_file</var> が <code>var</code> から <code>const</code> に変更された。
;0.3.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.3.0/#Hello-World
|title=Zig Documentation(0.3.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:0.2.0に同じ
;0.2.0<ref>{{Cite web
|url=https://ziglang.org/documentation/0.2.0/#Hello-World
|title=Zig Documentation(0.2.0)
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}
</syntaxhighlight>
;0.1.1<ref>{{Cite web
|url=https://ziglang.org/documentation/0.1.1/#hello-world
|title=Zig Documentation
|website=ziglang.org
|accessdate=2022-07-17
}}</ref>:<syntaxhighlight lang=zig>
const io = @import("std").io;
pub fn main() -> %void {
%%io.stdout.printf("Hello, world!\n");
}
</syntaxhighlight>
=== 環境準備 ===
Zigは、2022年7月の時点で '''pre-release''' の段階にあり、インストール手順も何度か変わっているので、まずは https://ziglang.org/learn/getting-started/ を参照し、最新のインストール手順を確認してください。また、ローカルのパッケージデータベースをパッケージシステムのリポジトリと同期を取り、鮮度の高い状態を維持するよう心がけてください。これは、インストール後も同じですし、zigに限ったことでもありません。
==== パッケージ マネージャー によるインストール ====
nightly の Zigを使いたい場合でない限り、お使いのOSやディストリビューションでサポートされているパッケージ マネージャを使ってインストールする事をお勧めします。
===== Windows =====
Zig は、[[Chocolatey]]パッケージシステムが対応しています。
:<syntaxhighlight lang=console>
> choco install zig
</syntaxhighlight>
{{See also|w:Chocolatey}}
===== macOS =====
macOS では、[[Homebrew]]と[[MacPorts]]が対応しています。
;最新とタグ付けされたリリース:<syntaxhighlight lang=console>
# brew install zig
</syntaxhighlight>
;Git の master ブランチの最新ビルド:<syntaxhighlight lang=console>
# brew install zig --HEAD
</syntaxhighlight>
;MacPorts:<syntaxhighlight lang=console>
# port install zig
</syntaxhighlight>
{{See also|w:Homebrew|w:MacPorts}}
===== FreeBSD =====
;pkg:<syntaxhighlight lang=console>
# pkg install zig
</syntaxhighlight>
;ports:<syntaxhighlight lang=console>
# make -C /usr/ports/lang/zig all install clean
</syntaxhighlight>
{{See also|w:Ports}}
===== GNU/Linuxのディストリビューション =====
いわゆるLinuxは、Linux(ここではOSカーネル)と、FSFがHurdカーネルのために設計・開発したGNUユーザーランド(OSの基本機能を提供するソフトウェアの集合)を組合わせたものです。
このように、LinuxカーネルとGNUユーザーランドを組合わせたソフトウェアプラットフォームをGNU/Linuxと呼びます<ref>GNU/Linuxの中核として、商用・非商用を問わず、再配布可能なユーティリティを収集・配布するディストリビューターが登場しました。これらのディストリビューターは、それぞれの配布物(互換性を失いがち)を、ディストリビューションとして区別する必要が生じました(特に、共有ライブラリの非互換性は目立ち、Linux支持者自身が嫌悪するWindowsのDLL-Hellに酷似しています)。 このようにして、ディストリビューション間の区別がなされたのです(また、ほかにもマーケティング上の理由などもあります)。<hr/>Unixでディストリビューションという言葉は、ソースコードで配布されるBSDのD (''distribution'') と関連付けられ、一方、非ソースコード指向のGNU/Linuxディストリビューションが、Unix訴訟の間隙を利する形で386 BSDのニッチをに受入れているのは皮肉なことです。</ref>
====== Fedora 36 ======
:<syntaxhighlight lang=console>
# dnf install zig
</syntaxhighlight>
{{See also|w:Dandified Yum}}
==== ソースコードからのビルド ====
Zig は、ソースコードが Github の https://github.com/ziglang/zig.git で公開されているので、必要に応じてソースコードからビルドすることができます。
とはいえ、zig はセルフホストに成功しているので、zig のビルドには zig が必要となり、クロスビルドしたバイナリーを持込むか、一旦、パッケージシステムからインストールする必要があります(FreeBSDのPortsが行っているのは、まさにこれです)。
ビルド方法こそ、頻繁に内容が変わるので個別具体的な手順は述べませんが、zig はコンパイラーであるとともにツールチェインでもあり、ビルドシステムも内包しているので、 zig build とすると build.zig ファイルに書かれているレシピにしたがって自動的にビルドが進行します(ストレージとメモリーと時間に余裕を見る必要があります)。
===== build & exec =====
zig コマンドは、コンパイラーにとどまらずビルドツールの機能を持ち、<code>run</code>サブコマンドは、当該ソースファイルの(ソースコードの変更やキャッシュ クリアーなど必要性があれば)コンパイルとコンパイルの成果物の実行を行います。これを「インタープリター風」と称することがありますが、二回目からはソースファイルを変更したりキャッシュをクリアーしない限りコンパイルのオーバーヘッドが不要で、キャッシュ内の実行形式が実行されるなど、ビルドツール/ビルドシステムとしての特徴が際立ち、逐次解釈的な要素は希薄(皆無)です<ref>crystal の <code>i/interactive</code> サブコマンドのように、真に対話的に実行する処理系も既にあるので、ビルドシステムの簡易呼出しとインタープリターを混同すべきではありません)</ref>。
;適用例:<syntaxhighlight lang=console>
zig run hello.zig
</syntaxhighlight>
===== プロジェクトの作成 =====
プログラミングの上で必須ではありませんが、プロジェクト単位でファイルやビルド手順を他からアイソレーションすることができ、zigコマンドにもそれを支援する機能があります。
プログラムの記述言語で、ビルドツールのレシピを書くことができるのは魅力的ですが、当の記述言語の習得中には有難みも半減なので、複数のソースに分割する規模になるまでは単に、zig ソースファイル で不都合はありません。
ここで作るプロジェクトの名前は myproj としましょう。
予め、作業用に適したファイルシステムに、ディレクトリー myproj を用意し、zig init-exe を実行します。
;myproj の雛型生成とスケルトンのままビルド(と実行):<syntaxhighlight lang=console>
% mkdir myproj/
% cd myproj/
% zig init-exe
% find -s * -type f
build.zig
src/main.zig
% cat build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("myproj", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
% cat src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
std.log.info("All your codebase are belong to us.", .{});
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
}
% zig build
% zig-out/bin/myproj
info: All your codebase are belong to us.
</syntaxhighlight>
== 基礎篇 ==
<!-- TODO:書くべき項目を並べてみましたが、例えば「値と型」だけでも網羅的に書いていくとコンテンツの分量が爆発するのが目に見えているので、過剰になったらリファレンス篇に移動するなどの方法で、各節はコンパクトさを心がけたいです。-->
=== コメント ===
Zigでは、<code>//</code> から行末までがコメントです。
C言語の <code>/* … */</code> のスタイルの複数行に渡るコメントは'''ありません'''。
これは、コードの各行を文脈に関係なくトークン化できるようにするためです。
;hello.zig:<syntaxhighlight lang=zig>
// hello.zig:
const std = @import("std"); // 先頭に @ が付く関数は組込み関数です
pub fn main() !void {
try std.io.getStdOut().writeAll("Hello, World!\n");
}
</syntaxhighlight>
==== Docコメント ====
Zigでは、<code>///</code> から始まるコメントは特別なコメントで、Docコメント( ''Doc comments'' )と呼ばれます。
Docコメントは特定の場所にしか許されません。式の途中や非Docコメントの直前など、予想外の場所にdocコメントがあると、コンパイルエラーになります。
[TODO:サンプルコードと整形結果]
==== トップレベルDocコメント ====
Zigでは、<code>//!</code> から始まるコメントは特別なコメントで、トップレベルDocコメント( ''Top-Level Doc Comments '' )と呼ばれます。
コンテナレベルのドキュメントのように、直後のドキュメントに属さないユーザードキュメントに、トップレベルDocコメントを使います。
[TODO:サンプルコードと整形結果]
DocコメントおよびトップレベルDocコメントは、コンパイル時に zig build-exe -femit-docs ソースファイル.zig の様に、-femit-docs をあたえると、 docs/ 以下にドキュメントが生成されます。
=== 値と型 ===
[TOD0:整数・浮動小数・論理値・文字列・共用体・構造体・列挙・配列・ベクトル・スライス・ポインター・ゼロビットな型, 関連する組込み関数]
;formatを伴うprintと値と型:<syntaxhighlight lang="zig">
pub fn main() !void {
const print = @import("std").io.getStdOut().writer().print;
try print(" (1) = {}\n", .{42});
try print(" (2) = {}\n", .{0x17});
try print(" (3) = {}\n", .{0o17});
try print(" (4) = {}\n", .{0b0100101});
try print(" (5) = {}\n", .{1e222});
try print(" (6) = {}\n", .{3.1415926536});
try print(" (7) = {}\n", .{'c'});
try print(" (8) = {c}\n", .{'c'});
try print(" (9) = {s}\n", .{"abcdef"});
try print("(10) = {}, {}\n", .{ 111, 999 });
try print("(11) = {1}, {0}\n", .{ 111, 999 });
try print("(12) = {1s}, {0}\n", .{ 111, "abc" });
try print("(13) = {0d}, {0b}, {0o}, {0x}, {0X}\n", .{ 123 });
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(1) = 42
(2) = 23
(3) = 15
(4) = 37
(5) = 1.0e+222
(6) = 3.1415926536e+00
(7) = 99
(8) = c
(9) = abcdef
(10) = 111, 999
(11) = 999, 111
(12) = abc, 111
(13) = 123, 1111011, 173, 7b, 7B
</syntaxhighlight>
: <code>print()</code>の前の、<code>try</code>は単項演算子です。<code>try</code> は、右の式が例外を投げると式の値にします。
:: エラーユニオン型を返す関数は、<code>try</code>単項演算子か<code>catch</code>二項演算子で、値とエラーを弁別する必要があります(<code>try</code>あるいは<code>catch</code>がないと、コンパイル時にエラーになります)。
: <code>print()</code>の様に、標準ライブラリの <code>format()</code>を使う関数は、'''書式化文字列'''と'''可変長配列''' <code>.{ … }</code> を引数にします。[[C言語/標準ライブラリ/ctype.h|C言語]]のような、可変引数'''ではなく'''可変長の配列を使うので<ref>printf() に代表される可変引数関数は利便性は高いですが、書式化文字列と引数の型不一致が生じると、スタックフレームを非可逆的に破壊します。これを未然に防ぐことは、コンパイル時の書式化文字列の解析と引数の型情報の照合で可能ですが、コンパイル時のメモリーと計算量(≒時間)の増大に直結します。</ref>、プレースホルダーがない場合でも、空の配列 <code>.{}</code> は必須です。
:;書式化文字列:通常の文字列ですが <code>{</code> と <code>}</code> で囲まれたプレスホルダーが、配列の当該順位の値(を書式化した文字列)に置換わります。
:;可変長配列
::書式化文字列のプレースホルダーのよって、参照と文字列化される値の配列です。
::2つ以上の値を渡す場合は、第二引数を .{ 1, 2, 3 } の様にカンマ区切りの配列にします( {} の前の . (点)を忘れがち)。
::基本的に、左から順にプレスホルダーに配列の値が左から与えられますが、{0} {1} の書式で参照する引数の順位を明示できます。
::書式指定と併用する時は、 <code> print("? = {1s}, {0}\n", .{ 111, "abc" })</code> の様に順位が先、書式指定文字が後になります。
:
:数値(整数と浮動小数点数)や文字・文字列のリテラルがあり、整数はいくつかの異なる基数表現が、浮動小数点数は指数表現と小数表現があります。
:文字と文字列は明確に異なり、リレラルでは ’A’ が文字、 ”ABC” が文字列です。
::嫌な予感がした人の直感は正解です。Zig では、文字列は第一級オブジェクト'''ではなく'''文字(u8)の配列で、関数から返すときはアロケータとdeferの連携などで記憶域の寿命と値の妥当性を「プログラマ」が担保する必要があります。また、[[Go]]のGCはありません。[[Crystal]]のASTを操作できるマクロもありませんし、[[Rust]]の所有権も、[[C++]]のスマートポインターもありません。
:::このことは、C言語なみのプログラマー任せのメモリー管理を文字列以外でも強いられることを意味していますが、zig(コマンド)のソースコードを読むと、複数の型でアロケータを使い分け、スタック上のインスタンス(のハードウェア起因のスコープ)を超絶技巧的に使い分けられることを実践で証明しているので、'''pre-'''releaseから、initial-releasまでの間に、安定化・定式化が図られることを期待します。
<!--
[TODO:[https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig master/lib/std/fmt.zig]を観て書いています。参照すべき標準ライブラリのドキュメントを発見出来たら、見直し]
[TODO:表組み]
-->
==== comptime ====
Zigでは、コンパイル時に'''式が既知かどうか'''という概念を重要視しています。
下記コードはコンパイルエラーになります。
:<syntaxhighlight lang="zig" line highlight=7>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = mul(3, 4);
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
;コンパイル結果:<syntaxhighlight lang=text>
An error occurred:
/tmp/playground130713503/play.zig:7:17: error: unable to evaluate constant expression
const ary: [len]i32 = undefined;
</syntaxhighlight>
: 「定数式が評価できない 」と宣っています。
: [[C++]]であれば、constexprが適用なケースですが、Zigでは次のような解決方法を取ります。下記コードはエラーになりません。
:<syntaxhighlight lang="zig" line highlight=6>
fn mul(x: usize, y: usize) usize {
return x * y;
}
pub fn main() void {
const len : usize = comptime mul(3, 4); // mul の前に comptime を追加
const ary: [len]i32 = undefined;
_ = ary;
}
</syntaxhighlight>
:変更点は mul() の呼出しを comptime で修飾しただけです。comptime は、修飾子式を'''コンパイル時に実行する'''修飾子で、式の中でコンパイル時に未定な値が参照されると、エラーとなります。ここでは、数リテラル同士の商を求めているので、コンパイル時値が確定できます。
: _ = ary は、「定義済だが参照のない変数宣言」をサプレッスするときのイディオムです。
<!--
const std = @import("std");
pub fn main() !void {
const i = 0;
const string = [_]i32{ 1, 2, 3, 4 };
for (string) |character, index| {
std.debug.print("character: {}, index: {}, :{s} \n", .{ character, index, @typeName(@TypeOf(character)) });
}
_ = i;
}
-->
=== テスト ===
=== 変数 ===
=== 制御構造 ===
[TODO:Zig の制御構造は文ではなく式]
==== 分岐 ====
[TODO:ifとswitch]
==== 反復 ====
[TODO:whileとfor]
=== 関数 ===
=== エラー ===
=== 演算子 ===
==== 優先順位 ====
高
<syntaxhighlight lang=text line>
x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % ** *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
</syntaxhighlight>
低
=== optional type ===
=== opaque ===
訳語未定
=== ブロック ===
[TODO:スコープとシャドーイング;deferはここ?]
=== キャスト ===
[TODO:Zig は強い型付け(); 型強制 (Type coercion) について]
=== アセンブリ言語との連携 ===
[TODO:所謂インラインアセンラ]
=== atomic ===
=== 非同期関数 ===
=== 組込み関数 ===
[TODO:組込み関数は、@で始まり、@TypeOfや@alignOfの他@sinや@memcpyも組込み関数]
=== メモリ管理 ===
=== キーワード一覧 ===
<code>align</code>
<code>allowzero</code>
<code>and</code>
<code>anyframe</code>
<code>anytype</code>
<code>asm</code>
<code>async</code>
<code>await</code>
<code>break</code>
<code>catch</code>
<code>comptime</code>
<code>const</code>
<code>continue</code>
<code>defer</code>
<code>else</code>
<code>enum</code>
<code>errdefer</code>
<code>error</code>
<code>export</code>
<code>extern</code>
<code>fn</code>
<code>for</code>
<code>if</code>
<code>inline</code>
<code>noalias</code>
<code>nosuspend</code>
<code>or</code>
<code>orelse</code>
<code>packed</code>
<code>pub</code>
<code>resume</code>
<code>return</code>
<code>linksection</code>
<code>struct</code>
<code>suspend</code>
<code>switch</code>
<code>test</code>
<code>threadlocal</code>
<code>try</code>
<code>union</code>
<code>unreachable</code>
<code>usingnamespace</code>
<code>var</code>
<code>volatile</code>
<code>while</code>
== チートシート ==
[TODO:文法と型と頻用する標準ライブラリの関数と型のアンチョコ]
== リファレンス篇 ==
== 脚註 ==
<references />
== 外部リンク ==
* [https://ziglang.org/ Home ⚡ Zig Programming Language] {{---}} 公式サイト
** [[https://ziglang.org/documentation/master/ Zig Language Reference]] {{---}} リファレンスマニュアル
* [https://github.com/ziglang/zig ziglang/zig: General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.] {{---}} 公式リポジトリ
* [https://zig-play.dev/ Zig Playground] {{---}} オンライン実行環境
** [https://github.com/gsquire/zig-play About An online Zig compiler inspired by Go and Rust] {{---}} リポジトリ
[[Category:zig|*]]
[[Category:プログラミング言語]]
0xwxtz2c8k0k3rx614ceb5jqcid6xsp
Crystal
0
35227
205796
205750
2022-07-24T14:05:06Z
Ef3
694
/* Ruby との違い */ 誤字脱字言換え
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Crystal (プログラミング言語)}}
本書は、[[w:Crystal (プログラミング言語)|Crystal]]のチュートリアルです。
'''Crystal'''は、Ary Borenszweig、Juan Wajnerman、Brian Cardiffと300人以上の貢献者によって設計・開発された[汎用オブジェクト指向プログラミング言語です<ref>{{Cite web
|url=https://github.com/crystal-lang/crystal/graphs/contributors
|title=Contributors
|accessdate=2022-07-18
|website=github.com
}}</ref>。[[Ruby]] にヒントを得た構文を持ち、静的型チェックを備えた [[コンパイル型言語]]ですが、変数やメソッドの引数の型は一般には不要です。型は高度なグローバル[[型推論]]アルゴリズムによって解決される。<ref>{{Cite web
|url=http://crystal-lang.org/2013/09/23/type-inference-part-1.html
|title=Type inference part 1
|last=Brian J.
|first=Cardiff
|date=2013-09-09
|accessdate=2022-07-18
|website=crystal-lang.org
}}</ref>Crystalは[[Apache License]]バージョン2.0のもと、FOSSとしてリリースされています。
__TOC__
== Hello, World! ==
他の多くのチュートリアルがそうであるように、
私たちもまずはCrystalの世界にあいさつすることから始めましょう。
Rubyとの比較も兼ねて、[[Ruby#Hello, World!]]をそのまま実行してみます。
''hello.cr''というファイルを作り、次のように書いて保存して下さい<ref>Crystalのソースファイルの拡張子は''.cr'' です</ref>。
;hello.cr:<syntaxhighlight lang=Crystal>
puts 'Hello, World!'
</syntaxhighlight>
;コマンドラインでの操作:<syntaxhighlight lang="console">
% cat hello.cr
puts 'Hello, World!'
% crystal hello.cr
In hello.cr:1:6
1 | puts 'Hello, World!'
^
Error: unterminated char literal, use double quotes for strings
% sed -i -e "s@'@Q@g" -e 's@Q@"@g' hello.cr
% cat hello.cr
puts "Hello, World!"
% crystal hello.cr
Hello, World!
</syntaxhighlight>
この1行のスクリプトは、メソッド<code>puts</code> に文字リテラル<code>"Hello, World!"</code>を渡し呼出しています。
このプログラムは、[[Ruby#Hello, World!]]と同じですが、Crystalでは文字列リテラルは <code>"…"</code> で囲うのでそれだけ変更しました。
== プログラミング環境 ==
Crystalのプログラムを作り、コンパイル・実装するには、「オンライン実行環境を使う」・「エディト・コンパイル・実行環境を用意してそれを使う」の2通りの方法があります。
=== オンライン実行環境 ===
公式のオンライン実行環境、 https://play.crystal-lang.org/ があります。
まずは、これを使って本書に例示されているコードを実行してみることをお勧めします。
=== エディト・コンパイル・実行環境 ===
エディタについては本書では触れませんが、プログラミング時間の大半はエディタの操作に費やされるため、良いエディタを選択することが重要です。
Crystal の言語処理系は、 https://crystal-lang.org/install/ から入手します。
自分の、OSやGNU/Linuxであればディストリビューションに合わせてインストールしてください。
また、FreeBSDのように crystal と shards が別パッケージとなっていることもあるので、その場合は shards も追加インストールします。
多くの場合、インストールされた、 crystal はスタティック リンクされているので、ダイナミック リンク版の crystal を入手するには、スタティック リンク版の実行ファイルとソースコードを入手し、スタティック リンク版でソースから crystal をコンパイル・インストールする必要があります。
=== crystal コマンド ===
crystal コマンドは Crystal のコンパイラであると同時に、ビルドツールなどを含んだツールチェインです(プログラミング言語のCrystalは、先頭を大文字、コマンドのcrystalは、先頭を小文字にして区別します)。
[TODO: コマンドラインツール crystal の解説。 crystal ファイル名 は crystal run ファイル名 の短縮形で、インタープリタ的な実行…ではなく、内部ビルドツールでコンパイル・実行を行う]
== Ruby との違い ==
Crystalは、Rubyに触発された構文を持つものの、Rubyとの互換性をゴールに定めては'''いません'''。
このため、細部を見ると仕様に差異があり、Rubyのソースコードをcrystalに掛けても前節の 'Hello World' の様にコンパイルに失敗することがあります。
また、コンパイルできても実行結果に違いが出ることがあります。
ここでは、Ruby との違いについて実際のコードと双方の結果を比較することで、差異についての理解を深めていきます。
=== 整数型の特性 ===
;大きな整数:<syntaxhighlight lang=Crystal>
p 2 ** 999
p (2 ** 999).class
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
Integer
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
Unhandled exception: Arithmetic overflow (OverflowError)
from /usr/local/share/crystal/share/crystal/src/int.cr:295:9 in '**'
from pow.cr:1:1 in '__crystal_main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:101:7 in 'main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:127:3 in 'main'
from /usr/local/lib64/libc.so.6 in '__libc_start_main'
from /usr/local/.cache/crystal/crystal-run-pow.tmp in '_start'
from ???
</syntaxhighlight>
: Ruby の整数は、桁あふれが起こると自動的に多倍長整数に型変換されるので、継ぎ目なしに大きな数を扱うアルゴルズムが使えます。
: Crystal の整数は、固定長です(大きさについては[[#リテラルと型|後述]])。なので大きな答えになる式を評価すると桁あふれが生じます。桁あふれが生じますが、C言語のように寡黙に処理を続けるのではなく、実行時に例外(OverflowError)が上がるので、例外を捕捉し然るべき処置を施すことが可能です。
==== BigInt ====
<code>big</code> を <code>require</code> すると <code>BigInt</code> が使えるようになります。
;BigInt:<syntaxhighlight lang=Crystal>
require "big"
p BigInt.new(2) ** 999
p (BigInt.new(2) ** 999).class
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
BigInt
</syntaxhighlight>
: BigIntはプリミティブではなので、リテラル表現はありません。また、
::<syntaxhighlight lang=Crystal>
n : BigInt = 2
</syntaxhighlight>
::<syntaxhighlight lang=console>
Error: type must be BigInt, not Int32
</syntaxhighlight>
:: のように型アノテーションすることも出来ません。
=== リテラルと型 ===
;様々なリテラルと型:<syntaxhighlight lang=Crystal>
[nil, false, true, 42, 2.73, 'Q', "string", [1,2,3], {a:1, b:2}].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
[nil, NilClass]
[false, FalseClass]
[true, TrueClass]
[42, Integer]
[2.73, Float]
["Q", String]
["string", String]
[[1, 2, 3], Array]
[{:a=>1, :b=>2}, Hash]
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
[nil, Nil]
[false, Bool]
[true, Bool]
[42, Int32]
[2.73, Float64]
['Q', Char]
["string", String]
[[1, 2, 3], Array(Int32)]
[{a: 1, b: 2}, NamedTuple(a: Int32, b: Int32)]
</syntaxhighlight>
: Crystal の整数は Int32、浮動小数点数は Float64 です。
;サイズを指定した数リテラル:<syntaxhighlight lang=Crystal>
[1_i64, 2_u32, 3_u64, 4_i32, 5_i16, 6_u8, 7_i128, 8_u128, 3.14_f32, 1.44_f64].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;ruby:Rubyでは、サーフィックスの付いた数値リテラルは無効
;crystalの実行結果:<syntaxhighlight lang="console">
[1, Int64]
[2, UInt32]
[3, UInt64]
[4, Int32]
[5, Int16]
[6, UInt8]
[7, Int128]
[8, UInt128]
[3.14, Float32]
[1.44, Float64]
</syntaxhighlight>
: Crystal では、数値リテラルに _ で始まるサーフィックスを付け { i:符号付き整数, u:符号なし整数, f:浮動小数点数 } と { 8,16,32,64,128 } のビット幅の組合せです<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/literals/ Literals]</ref>。
=== for式がない ===
Crystal には、Ruby にはある for式がありません。
;Rubyのfor式の構文:<syntaxhighlight lang="ruby">
for 変数 in コレクション
文
end
</syntaxhighlight>
:コレクションは Range, Array, Hash など内部構造を持つオブジェクトです。
:for式は、最後に評価した値を返すので、for'''式'''です。
;for式のeachメソッドによる置換え:<syntaxhighlight lang="ruby">
for x in [ 2, 3, 5, 7, 11 ] do
p x
end
# ↓
[ 2, 3, 5, 7, 11 ].each do | x |
p x
end
</syntaxhighlight>
: の様にコレクションの each メソッドで置換え可能なので、Rubyからの移植でも小規模な書換えで済みます<ref>[https://github.com/crystal-lang/crystal/issues/830 "For" Loop support #830]</ref>(後述のマクロで実装できないかと思いましたが、いまのところ無理のようです)。
また loop 式もありませんが while true; … end で間に合います。Ruby では while 式の条件の次に do が置けますが、Crystal では置けません。
=== eval()がない ===
Crystal には eval() はありません。
Crystalはコンパイル型言語ですので、無理もないことです。
もし、Crystal で eval() を実装しようとすると、Common Lisp の様にインタープリターを丸ごとランタイムに含む必要があります。
これはリーズナブルな選択ではありません。
Crystal では、eval() が必要なケースに(限定的ですが)マクロを使うことで実現出来る可能性があります。
=== マクロ ===
Crystalには、Rubyにはないマクロがあります<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/macros/ Macros - Crystal]</ref>。Rubyは実行時にすべてのオブジェクトにアクセス出来て、メソッド生やし放題なのでマクロは必要ありませんが、Crystalはコンパイル時に型やメソッドを確定する必要があり、特にメソッドジェネレターとしてのマクロにニーズがあります。また、テンプレート言語的なマクロなので、環境変数による条件分岐や、コンテナを渡し繰返し処理する構文もあります(面白いことにマクロには for 文があり、反対にマクロの中では、eachメソッドは使えません)。マクロには <code><nowiki>{{</nowiki>attr.id}}</code> の様にASTへのアクセス手順が用意されており、半ば言語を拡張するようなアプローチを取ることも出来ます。
[TODO:ASTについての解説;コラム向き?]
;マクロを使ったattr_accessorのイミュレーション:<syntaxhighlight lang=crystal>
class Point
def initialize(@x : Int32, @y : Int32)
end
# macro定義
macro attr_accessor(*attrs)
{% for attr in attrs %}
def {{attr.id}}() @{{attr.id}} end
def {{attr.id}}=(var) @{{attr.id}} = var end
{% end %}
end
# macro呼出し
attr_accessor :x, :y
end
pt = Point.new(20, 30)
p [pt.x, pt.y]
t = pt.x
pt.x = pt.y
pt.y = t
p [pt.x, pt.y]
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
[20, 30]
[30, 20]
</syntaxhighlight>
: Ruby には、attr_accessor と言う「クラスのメンバーのアクセサーを自動生成するメソッド」がありますが、Crystalにはないようなので、マクロで実装しました。
:: attr_accessor :name からは
::<syntaxhighlight lang=ruby>
def name() @name end
def name=(val) @name = val end
</syntaxhighlight>相当のコードが生成されます。
[TODO:マクロの機能と構文の説明 *の付いた引数、 <nowiki>{{</nowiki>引数}}、{% … %} 構文]
==== マクロ p! ====
メソッド p は、与えられた「式」の inspaect() の返す値を puts しますが、マクロ p! は、それに先んじて(評価前の)「式」を表示します<ref>[https://crystal-lang.org/api/1.5.0/Crystal/Macros.html#p%21%28%2Aexpressions%29%3ANop-instance-method def p!(*expressions) : Nop]</ref>。
;p!の例:<syntaxhighlight lang=crystal>
x, y = true, false
p! x,y,x && y, x || y, x ^ y, !x, x != y, x == y
ary = [ 1, 2, 3 ]
p! ary
p! ary.map(&. << 1)
p! ary.map(&.to_f)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
x # => true
y # => false
x && y # => false
x || y # => true
x ^ y # => true
!x # => false
x != y # => true
x == y # => false
ary # => [1, 2, 3]
ary.map(&.<<(1)) # => [2, 4, 6]
ary.map(&.to_f) # => [1.0, 2.0, 3.0]
</syntaxhighlight>
===== 入れ子のp! =====
マクロ p! は入れ子に出来ます。また、一旦ASTに変換してから再度ソースコードに変換するので、等価な別の構文に変換されることがあります。
;入れ子のp!:<syntaxhighlight lang=crystal>
p! (
100.times{|i|
p! i
break i if i > 12
}
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(100.times do |i|
p!(i)
if i > 12
break i
end
end) # => i
# => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
i # => 6
i # => 7
i # => 8
i # => 9
i # => 10
i # => 11
i # => 12
i # => 13
13
</syntaxhighlight>
=== クラス ===
==== シンプルなクラス ====
;シンプルなクラス:<syntaxhighlight lang=crystal highlight="2" line>
class Hello
def initialize(@name : String = "World")
end
def greeting
puts "Hello #{@name}!"
end
end
hello = Hello.new()
hello.greeting
universe = Hello.new("Universe")
universe.greeting
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Hello World!
Hello Universe!
</syntaxhighlight>
:;初期化メソッド
:: <syntaxhighlight lang=crystal line start=4>
def initialize(@name : String = "World")
end
</syntaxhighlight>
::Rubyであれば
:: <syntaxhighlight lang=ruby line start=4>
def initialize(name = "World")
@name = name
end
</syntaxhighlight>
::とするところですが、Crystalでは、型アノテーション <code> : String</code> を使い、引数の型を限定しました。
::また、(@ 付きの)アトリビュート名を仮引数にすると、そのままアトリビュート(a.k.a. インスタンス変数)に仮引数が代入されます。
::これは、C++のコンストラクターのメンバー初期化リストと同じアイディアですが、Crystalではインスタンス変数に @ が前置されるので、仮引数に @ が出現すればインスタンス変数の初期値だと自明で、聡明な選択です。
==== 都市間の大圏距離 ====
[[Ruby#ユーザー定義クラス]]の都市間の大圏距離を求めるメソッドを追加した例を、Crystalに移植しました。
;都市間の大圏距離:<syntaxhighlight lang=crystal highlight=”2,7,12” line>
class GeoCoord
getter :longitude, :latitude
def initialize(@longitude : Float64, @latitude : Float64)
end
def to_s(io)
ew, ns = "東経", "北緯"
long, lat = @longitude, @latitude
ew, long = "西経", -long if long < 0.0
ns, lat = "南緯", -lat if lat < 0.0
io << "(#{ew}: #{long}, #{ns}: #{lat})"
end # https://github.com/crystal-lang/crystal/issues/259
def distance(other)
i, r = Math::PI / 180, 6371.008
Math.acos(Math.sin(@latitude*i) * Math.sin(other.latitude * i) +
Math.cos(@latitude*i) * Math.cos(other.latitude * i) * Math.cos(@longitude * i - other.longitude * i)) * r
end
end
# メソッドの先頭を大文字に出来ないのでクラス名のメソッドは作ることが出来ない
# def GeoCoord(lng : Float64, lat : Float64)
# GeoCoord.new(lng, lat)
# end
Sites = {
"東京駅": GeoCoord.new(139.7673068, 35.6809591),
"シドニー・オペラハウス": GeoCoord.new(151.215278, -33.856778),
"グリニッジ天文台": GeoCoord.new(-0.0014, 51.4778),
}
Sites.each { |name, gc|
puts "#{name}: #{gc}"
}
puts ""
keys, len = Sites.keys, Sites.size
keys.each_with_index { |x, i|
y = keys[(i + 1) % len]
puts "#{x} ⇔ #{y}: #{Sites[x].distance(Sites[y])} [km]"
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
東京駅: (東経: 139.7673068, 北緯: 35.6809591)
シドニー・オペラハウス: (東経: 151.215278, 南緯: 33.856778)
グリニッジ天文台: (西経: 0.0014, 北緯: 51.4778)
東京駅 ⇔ シドニー・オペラハウス: 7823.269299386704 [km]
シドニー・オペラハウス ⇔ グリニッジ天文台: 16987.2708377249 [km]
グリニッジ天文台 ⇔ 東京駅: 9560.546566490015 [km]
</syntaxhighlight>
:Crystal には、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> はありませんが、標準ライブラリーのマクロに <syntaxhighlight lang=crystal inline> getter </syntaxhighlight>があるので
:: <syntaxhighlight lang=crystal line start=2>
getter :longitude, :latitude
</syntaxhighlight>
::としました。
::将来、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> が実装される可能性はありますが、姉妹品の<syntaxhighlight lang=crystal inline> setter </syntaxhighlight> との併用が下位互換性を考えると確実です。
: to_s は、Ruby ならば
:: <syntaxhighlight lang=ruby line start=7>
def to_s()
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
"(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
:: ですが、Crystalでは追加の引数 <var>io</var> が必要で
:: <syntaxhighlight lang=ruby line start=7>
def to_s(io)
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
io << "(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
: Ruby にはクラス名と同じ名前のメソッドで .new を呼出す文化があるのですが、Crystalはメソッドの先頭を大文字に出来ないので、これは見送りました。
==== 包含と継承 ====
[[JavaScript/クラス#包含と継承]]を、Rubyに移植した[[Ruby#包含と継承]]を、Crystalに移植しました。
;包含と継承の例:<syntaxhighlight lang=crystal line>
class Point
def initialize(@x = 0, @y = 0)
end
def inspect(io)
io << "x:#{@x}, y:#{@y}"
end
def move(dx = 0, dy = 0)
@x, @y = @x + dx, @y + dy
self
end
end
class Shape
def initialize(x = 0, y = 0)
@location = Point.new(x, y)
end
def inspect(io)
@location.inspect(io)
end
def move(x, y)
@location.move(x, y)
self
end
end
class Rectangle < Shape
def initialize(x = 0, y = 0, @width = 0, @height = 0)
super(x, y)
end
def inspect(io)
super(io)
io << ", width:#{@width}, height:#{@height}"
end
end
rct = Rectangle.new(12, 32, 100, 50)
p! rct,
rct.is_a?(Rectangle),
rct.is_a?(Shape),
rct.is_a?(Point),
rct.move(11, 21)
(END)</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
rct # => x:12, y:32, width:100, height:50
rct.is_a?(Rectangle) # => true
rct.is_a?(Shape) # => true
rct.is_a?(Point) # => false
rct.move(11, 21) # => x:23, y:53, width:100, height:50
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy inclusion-and-inheritance.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (16 bytes)
. @location : Point (8 bytes)
|
+- class Rectangle (24 bytes)
@width : Int32 (4 bytes)
@height : Int32 (4 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
===== superclass と subclasses =====
Crystal には、RubyのClassにあるメソッド superclass と subclasses がないので、マクロで実装しました。
;superclass と subclasses:<syntaxhighlight lang=crystal line>
class Class
def self.superclass
{{ @type.superclass }}
end
def self.subclasses : Array(self.class)
{{ @type.subclasses }}.map(&.as(self.class))
end
def self.all_subclasses : Array(self.class)
{% begin %}
[{{ @type.all_subclasses.join(",").id }}] of self.class
{% end %}
end
end
class A end
class AA < A end
class AAA < AA end
class AAB < AA end
class AB < A end
p! A,
A.subclasses,
A.all_subclasses,
AAA.superclass,
A.superclass
c = AAA
while !c.is_a? Nil
p! c.superclass
c = c.superclass
end</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
A # => A
A.subclasses # => [AA, AB]
A.all_subclasses # => [AA, AAA, AAB, AB]
AAA.superclass # => AA
A.superclass # => Reference
c.superclass # => AA
c.superclass # => A
c.superclass # => Reference
c.superclass # => Object
c.superclass # => nil
</syntaxhighlight>
==== 抽象クラス ====
[[Java/抽象クラス]]を、Crystalに移植しました。
;抽象クラスの宣言:<syntaxhighlight lang=Java>
abstract class クラス名
#
end
</syntaxhighlight>
: このクラス名は、 .new でインスタンス化出来ません。
:: Error: can't instantiate abstract class クラス名
: となります。
:インスタンス化することは出来ませんが、抽象クラスを別のクラスが継承する事は出来ます。
:また、抽象クラスを <code>super()</code> を使うことでメソッドを呼び出せるので、抽象メソッドではないメソッド(具象メソッド)を持つことも、インスタンス変数も持つことも出来ます。
:'''抽象クラスの例'''では、Shapeのinitializeメソッドが抽象クラスの具象メソッドとなっています。
;抽象メソッドの宣言:<syntaxhighlight lang=Java>
abstract def メソッド名
</syntaxhighlight>
: 派生先のクラスで、「メソッド名」を定義(def)し忘れると
:: Error: abstract `def クラス名#メソッド名()` must be implemented by クラス名
: となります
;抽象クラスの例:<syntaxhighlight lang=crystal line>
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
class Recrangle < Shape
def initialize(x, y, @w = 0.0, @h = 0.0)
super(x, y)
end
def to_s(io)
io << "Rectanle(#{@x}, #{@y}, #{@w}, #{@h})"
end
def area
@w * @h
end
end
class Circle < Shape
def initialize(x, y, @r = 0.0)
super(x, y)
end
def to_s(io)
io << "Circle(#{@x}, #{@y}, #{@r})"
end
def area
3.1425926536 * @r * @r
end
end
shapes = [
Square.new(5.0, 10.0, 15.0),
Recrangle.new(13.0, 23.0, 20.0, 10.0),
Circle.new(3.0, 2.0, 20.0),
] of Shape
shapes.each do |shape|
puts("#{shape}: #{shape.area}")
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Square(5.0, 10.0, 15.0): 225.0
Rectanle(13.0, 23.0, 20.0, 10.0): 200.0
Circle(3.0, 2.0, 20.0): 1257.03706144
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy abstract.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (24 bytes)
. @x : Float64 (8 bytes)
. @y : Float64 (8 bytes)
|
+- class Circle (32 bytes)
| @r : Float64 (8 bytes)
|
+- class Recrangle (40 bytes)
| @w : Float64 (8 bytes)
| @h : Float64 (8 bytes)
|
+- class Square (32 bytes)
@wh : Float64 (8 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
: 「包含と継承の例」と比べると、ShapeとRectangleが同じ階層にあることがわかると思います。
[TODO:virtual class::いい例がない]
== キーワード ==
Crystalのキーワード( ''keywords'' ) は、以下の通り。
<code>abstract</code> <code>alias</code> <code>as</code> <code>asm</code> <code>begin</code> <code>break</code> <code>case</code> <code>class</code> <code>def</code> <code>do</code> <code>else</code> <code>elsif</code> <code>end</code> <code>ensure</code> <code>enum</code> <code>extend</code> <code>for</code> <code>fun</code> <code>if</code> <code>include</code> <code>instance_sizeof</code> <code>lib</code> <code>macro</code> <code>module</code> <code>next</code> <code>of</code> <code>out</code> <code>pointerof</code> <code>private</code> <code>protected</code> <code>rescue</code> <code>return</code> <code>require</code> <code>select</code> <code>sizeof</code> <code>struct</code> <code>super</code> <code>then</code> <code>type</code> <code>typeof</code> <code>uninitialized</code> <code>union</code> <code>unless</code> <code>until</code> <code>when</code> <code>while</code> <code>with</code> <code>yield</code>
<!--
<code>__DIR__</code> <code>__END_LINE__</code> <code>__FILE__</code> <code>__LINE__</code>
-->
== 演算子 ==
Crystalは、1つ、2つ、または3つのオペランドを持つ数多くの演算子をサポートしています<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/operators.html Operators]access-date:2022-07-22</ref>。
演算子式は、実際にはメソッド呼び出しとしてパースされます。例えば、<code>a + b</code> は <code>a.+(b)</code> と意味的に同じで、引数 b を持つ a のメソッド + を呼び出すことになります。
{| class="wikitable"
|+ 演算子の優先度
!種類
!演算子
|-
|インデックス アクセサー
|<code>[]</code>, <code>[]?</code>
|-
|単項
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>, <code>!</code>, <code>~</code>
|-
|指数
|<code>**</code>, <code>&**</code>
|-
|乗除
|<code>*</code>, <code>&*</code>, <code>/</code>, <code>//</code>, <code>%</code>
|-
|加減
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>
|-
|シフト
|<code><<</code>, <code>>></code>
|-
|ビット間 AND
|<code>&</code>
|-
|ビット間 OR/XOR
|<code><nowiki>|</nowiki></code>,<code>^</code>
|-
|等値
|<code>==</code>, <code>!=</code>, <code>=~</code>, <code>!~</code>, <code>===</code>
|-
|比較
|<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>, <code><=></code>
|-
|論理 AND
|<code>&&</code>
|-
|論理 OR
|<code><nowiki>||</nowiki></code>
|-
|Range
|<code>..</code>, <code>...</code>
|-
|条件
|<code>?:</code>
|-
|代入
|<code>=</code>, <code>[]=</code>, <code>+=</code>, <code>&+=</code>, <code>-=</code>, <code>&-=</code>, <code>*=</code>, <code>&*=</code>, <code>/=</code>, <code>//=</code>, <code>%=</code>, <code><nowiki>|=</nowiki></code>, <code>&=</code>,<code>^=</code>,<code>**=</code>,<code><<=</code>,<code>>>=</code>, <code><nowiki>||=</nowiki></code>, <code>&&=</code>
|-
|スプラット
|<code>*</code>, <code>**</code>
|}
== 制御構造 ==
'''[[w:制御構造|制御構造]]'''(せいぎょこうぞう、''control flow'')とは、「順次」「分岐」「反復」という基本的な処理のことを言います。
{{コラム|Crystalの真理値|2=
制御構造は「条件式」が真であるか偽であるかによって分岐や反復の振る舞いが変わります。
では「条件式」が真・偽はどの様に決まるのでしょう?
Crystalでは <code>false</code> あるいは <code>nil</code> であると偽、それ以外が真です。
なので <code>0</code> も <code>[]</code>(空のArray) も <code>{}</code>(空のNamedTuple)も真です。
}}
=== 条件分岐 ===
Crystalの条件分岐には、[[#if|if]], [[#until|until]] と [[#case|case]]の3つの構文があります。
==== if ====
'''[[w:if|if]]'''は条件式によって実行・否を切り替える構造構文で、評価した式の値を返すので条件演算子でもあります。
;ifの例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
if a < 0
puts "minus"
elsif a > 0
puts "plus"
elsif a == 0
puts "zero"
else
puts a
end
p! (
if a < 0
"minus"
elsif a > 0
"plus"
elsif a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(if a < 0
"minus"
else
if a > 0
"plus"
else
if a == 0
"zero"
else
a
end
end
end) # => NaN
</syntaxhighlight>
:; elsif節:ifは、オプショナルな elsif 節を設け、条件式が偽であった時に別の条件に合致した処理を実行させることが出来ます。
:; else節:ifは、オプショナルな else 節を設け、条件式が偽であった時に処理を実行させることが出来ます。
: ifは値を返すので、メソッドの実引数に使うことが出来ますし、代入演算の右辺にも使えます。
==== 後置のif ====
Crystalには、RubyやPerlのような後置のifがあります。
;後置のifの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" if n == 0
puts "nは1" if n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは0
</syntaxhighlight>
==== unless====
'''unless'''(アンレス)は条件式によって実行・否を切り替える構造構文ですが、ifとは条件式に対する挙動が逆です。
;unless文の例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
unless a == 0
puts "Non-zero"
else
puts a
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Non-zero
</syntaxhighlight>
:; else節 : unless文は、オプショナルな else 節を設け、条件式が真であった時に処理を実行させることが出来ます。
::また、unless文は elsif 節は持てません。
==== 後置のunless ====
Crystalには、RubyやPerlのような後置のunlessがあります。
;後置のunlessの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" unless n == 0
puts "nは1" unless n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは1ではない
</syntaxhighlight>
==== case ====
caseは、複数の条件式によって処理を降る分ける用途の為に用意されています。
;caseの例:<syntaxhighlight lang=crystal line>
n = 2
case n
when 1
puts "one"
when 2
puts "two"
when 3
puts "three"
else
puts "other"
end
p! (
case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
two
(case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end) # => "two"</syntaxhighlight>
:C言語系のswitch文に慣れた人はbreakがないことに気がつくと思います。Crystalのcaseはfall throughしませんし、fall throughさせる方法もありません。
===== when節が定数でなく式を受付けます =====
[[#if|if]]を使ったコードをcaseに書き換えてみましょう。
;case の式の省略:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
case
when a < 0
puts "minus"
when a > 0
puts "plus"
when a == 0
puts "zero"
else
puts a
end
p! (
case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end) # => NaN
</syntaxhighlight>
このコードは when 節の式の値とcaseの式を <code>===</code> で比較し、最初に一致した when に対応する式が実行される事を利用しています。
===== 型による分岐 =====
when 節が式ではなく型であった場合、caseの式を <code>is_a?</code> で評価し、最初に一致した when に対応する式が実行されます。
;型による分岐:<syntaxhighlight lang=crystal line>
p! 0.class,
0.is_a?(Object),
0.is_a?(Int32),
0.is_a?(Number),
0.is_a?(String)
case 0
when String
puts "String"
when Number
puts "Number"
when Int32
puts "Int32"
when Object
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0.class # => Int32
0.is_a?(Object) # => true
0.is_a?(Int32) # => true
0.is_a?(Number) # => true
0.is_a?(String) # => false
Number
</syntaxhighlight>
暗黙のオブジェクト構文を使うと
:<syntaxhighlight lang=crystal line>
case 0
when .is_a?(String)
puts "String"
when .is_a?(Number)
puts "Number"
when .is_a(Int32)
puts "Int32"
when .is_a(Object)
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
:と書くことが出来ます。
:: メソッドは、.is_a? に限定しないので、 .odd? .even? .include? など Bool を返すメソッドなら何でも使えます。
when に対応する式は、1つのことが珍しくないので、その場合は省略可能な then を補うと、1行で書けます。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
[TODO:タプルとダミー識別子 _ ]
===== 網羅性の検査 =====
when の代わりに in を使用すると、exhaustive case 式が作成されます。exhaustive case では、必要な in 条件を省略するとコンパイル時にエラーとなります。排他的論理和では、when 節と else 節を含むことはできません。
コンパイラは、以下の in 条件をサポートしています。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
caseの式がユニオンの場合、各要素型を条件として使用することができる。
;組合型チェック:<syntaxhighlight lang=crystal line>
var : ( Bool | Int32 | Float64 )?
var = 3.14
p! (
case var
in Bool then var ? 1 : 0
in Int32 then var
in Float64 then var.to_i
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
(case var
in Bool
var ? 1 : 0
in Int32
var
in Float64
var.to_i
end) # => 3
</syntaxhighlight>
[TODO:case in は enum にも使える]
[TODO:短絡評価 && || ]
=== 繰返し ===
Crystalには、他のプログラミング言語のような[[#繰返し構文|繰返し構文]]と、[[#イテレーターメソッド|イテレーターメソッド]]があります。
==== 繰返し構文 ====
Crystalの繰返し構文には、while と untilの2つがあります<ref>for も do-while も loop もありません。</ref>。
===== while =====
while(ホワイル)は条件が'''真'''である間、式を実行しつづけます。
;構文:<syntaxhighlight lang=crystal>
while 条件式
式1
式2
:
式n
end
</syntaxhighlight>
: Rubyと違い、条件式の後ろに <code>do</code> をつけることは出来ません。
;while文のコード例:<syntaxhighlight lang=crystal line>
i = 0
p! (
while i < 10
p! i
i += 1
break i if i > 5
end
)
</syntaxhighlight>
: 2行目の <code>i < 5</code>が真の間、次の2行を繰返します。
: 4行目の <code>i += 1</code> は <code>i = i + 1</code> の構文糖
;実行結果:<syntaxhighlight lang="text">
(while i < 10
p!(i)
i = i + 1
if i > 5
break i
end
end)# =>
i # => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
6
</syntaxhighlight>
===== until =====
until(アンティル)は条件が'''偽'''である間、式を実行しつづけます。whileとは条件に対する挙動が逆です。
;構文:<syntaxhighlight lang=crystal>
until 条件式 [ do ]
文1
文2
:
文n
end
</syntaxhighlight>
: <code>do</code> は省略できます。
;untilのコード例:<syntaxhighlight lang=crystal line>
i = 0
until i == 3
puts i
i += 1
end
</syntaxhighlight>
: 2行目の <code>i == 3</code>が偽の間、次の2行を繰返します。
;実行結果:<syntaxhighlight lang="text">
0
1
2
</syntaxhighlight>
===== for =====
Crystalにはforがありませんが、コレクションのイテレーションメソッドを使うことで繰返しを簡素に実現出来ます。
==== Rangeオブジェクト ====
Rangeオブジェクトは、整数の区間を表し範囲演算子 <code>開始 ... 終了</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
rng = 1..3
puts rng.class
rng.each do | n |
puts "#{n}番";
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Range(Int32, Int32)
1番
2番
3番
</syntaxhighlight>
==== Arrayオブジェクト ====
Arrayオブジェクトは、任意の Crystal オブジェクトを要素として持つことができます。
配列式<code>[要素1, 要素2, … 要素n]</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
animals = ["ネコ", "金魚", "ハムスター"]
puts animals.class
animals.each do | animal |
puts "動物 #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Array(String)
動物 ネコ
動物 金魚
動物 ハムスター
</syntaxhighlight>
==== NamedTupleオブジェクト ====
NamedTupleオブジェクトは、任意の Crystal オブジェクトをキーに、任意の Crystal オブジェクトを値に持つことができる連想配列です。
NamedTuple式<code>{キー1 => 値1, キー2 => 値2, キーn => 値n}</code> で生成します。
また、キーが Symbol の場合
NamedTuple式<code>{キー1: 値1, キー2: 値2, キーn: 値n}</code> で生成することが出来ます。
;コード:<syntaxhighlight lang=crystal>
animals = {cat: "ネコ", gold_fish: "金魚", hamster: "ハムスター"}
puts animals.class
animals.each do | en, animal |
puts "動物 #{en}: #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NamedTuple(cat: String, gold_fish: String, hamster: String)
動物 cat: ネコ
動物 gold_fish: 金魚
動物 hamster: ハムスター
</syntaxhighlight>
このように、Crystalではforがなくてもコレクションのメソッドで同様の処理を実現できます。
===== loop =====
loop、ありません。
while true で代用します。
;loopの代用コード例:<syntaxhighlight lang=crystal line>
i = 1
while true
puts "0b%b" % i
i <<= 1
break if i > 2**8
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0b1
0b10
0b100
0b1000
0b10000
0b100000
0b1000000
0b10000000
0b100000000
</syntaxhighlight>
:5行目の、<code>break if i > 2**8</code>でループを脱出するようにしています。この様に break や return あるいは例外が上がらないとループは永久に終わりません。
:このコードは、Crystalにはない do-while文を模倣する例にもなっています。
==== イテレーターメソッド ====
===== Integer#times =====
Integer#timesは与えられたブロックをオブジェクトの示す整数値回くりかえします。
:コード<syntaxhighlight lang=crystal>
3.times{ puts "Hello, world!" }
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello, world!
Hello, world!
Hello, world!
</syntaxhighlight>
;繰返したい処理が2行以上ある場合:<syntaxhighlight lang=crystal>
3.times {
puts "Hello"
puts "World"
puts ""
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello
World
Hello
World
Hello
World
</syntaxhighlight>
;ループ変数を使た例:<syntaxhighlight lang=crystal>
3.times do |i|
puts "#{i}の倍は#{2 * i}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0の倍は0
1の倍は2
2の倍は4
</syntaxhighlight>
;ブロックを伴わないtimesメソッド:<syntaxhighlight lang=crystal>
iter = 3.times
puts iter.class
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
# puts iter.next # `next': StopIteration: iteration reached an end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Int::TimesIterator(Int32)
iter.next # => 0
iter.next # => 1
iter.next # => 2
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
</syntaxhighlight>
: Integer#times にブロックを渡さないと、Int::TimesIterator([T])オブジェクトが返ります。
: Int::TimesIterator([T])オブジェクトは外部イテレーターと呼ばれnextメソッドで反復を行えます。
== メソッド ==
=== クラスのメソッド一覧 ===
Crystal には、Objectクラスにmethodsメソッドがないので、マクロで実装しました。
;RubyのObject#methods:<syntaxhighlight lang=ruby>
p Object.methods.sort,
Integer.methods.sort,
Float.methods.sort,
Array.methods.sort,
Range.methods.sort
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :sqrt, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :[], :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
</syntaxhighlight>
;Crystalに実装したmethodsマクロ:<syntaxhighlight lang=crystal>
class Object
macro methods
{{ @type.methods.map(&.name.stringify).sort.uniq }}
end
end
p! Object.methods,
Reference.methods,
Array.methods,
Box.methods,
Channel.methods,
Deque.methods,
Dir.methods,
Exception.methods,
ArgumentError.methods,
DivisionByZeroError.methods,
IndexError.methods,
InvalidByteSequenceError.methods,
Fiber.methods,
Hash.methods,
IO.methods,
File.methods,
Mutex.methods,
PrettyPrint.methods,
Process.methods,
Regex.methods,
String.methods,
Thread.methods,
Bool.methods,
Int32.methods,
Float64.methods,
Proc.methods
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Object.methods # => ["!=", "!~", "==", "===", "=~", "class", "crystal_type_id", "dup", "hash", "in?", "inspect", "itself", "not_nil!", "pretty_inspect", "pretty_print", "tap", "to_s", "try", "unsafe_as"]
Reference.methods # => ["==", "dup", "exec_recursive", "exec_recursive_clone", "hash", "inspect", "object_id", "pretty_print", "same?", "to_s"]
Array.methods # => ["&", "*", "+", "-", "<<", "<=>", "==", "[]", "[]=", "[]?", "calculate_new_capacity", "check_needs_resize", "check_needs_resize_for_unshift", "clear", "clone", "compact", "compact!", "concat", "delete", "delete_at", "dup", "each_repeated_permutation", "fill", "first", "flatten", "increase_capacity", "increase_capacity_for_unshift", "index", "initialize", "insert", "inspect", "internal_delete", "last", "map", "map_with_index", "needs_resize?", "pop", "pop?", "pretty_print", "product", "push", "reject!", "remaining_capacity", "repeated_permutations", "replace", "reset_buffer_to_root_buffer", "resize_if_cant_insert", "resize_to_capacity", "resize_to_capacity_for_unshift", "reverse", "root_buffer", "rotate", "rotate!", "select!", "shift", "shift?", "shift_buffer_by", "shift_when_not_empty", "shuffle", "size", "size=", "skip", "sort", "sort!", "sort_by", "sort_by!", "to_a", "to_lookup_hash", "to_s", "to_unsafe", "to_unsafe_slice", "transpose", "truncate", "uniq", "uniq!", "unsafe_fetch", "unsafe_put", "unshift", "unstable_sort", "unstable_sort!", "unstable_sort_by", "unstable_sort_by!", "|"]
Box.methods # => ["initialize", "object"]
Channel.methods # => ["close", "closed?", "dequeue_receiver", "dequeue_sender", "initialize", "inspect", "pretty_print", "receive", "receive?", "receive_impl", "receive_internal", "receive_select_action", "receive_select_action?", "send", "send_internal", "send_select_action"]
Deque.methods # => ["+", "<<", "==", "buffer", "clear", "clone", "concat", "delete", "delete_at", "dup", "each", "halfs", "increase_capacity", "initialize", "insert", "inspect", "internal_delete", "pop", "pop?", "pretty_print", "push", "reject!", "rotate!", "select!", "shift", "shift?", "size", "size=", "to_s", "unsafe_fetch", "unsafe_put", "unshift"]
Dir.methods # => ["children", "close", "each", "each_child", "entries", "initialize", "inspect", "path", "pretty_print", "read", "rewind", "to_s"]
Exception.methods # => ["backtrace", "backtrace?", "callstack", "callstack=", "cause", "initialize", "inspect", "inspect_with_backtrace", "message", "to_s"]
ArgumentError.methods # => ["initialize"]
DivisionByZeroError.methods # => ["initialize"]
IndexError.methods # => ["initialize"]
InvalidByteSequenceError.methods # => ["initialize"]
Fiber.methods # => ["cancel_timeout", "dead?", "enqueue", "initialize", "inspect", "makecontext", "name", "name=", "next", "next=", "previous", "previous=", "push_gc_roots", "resumable?", "resume", "resume_event", "run", "running?", "stack_bottom", "stack_bottom=", "timeout", "timeout_event", "timeout_select_action", "timeout_select_action=", "to_s"]
Hash.methods # => ["==", "[]", "[]=", "[]?", "add_entry_and_increment_size", "clear", "clear_entries", "clear_impl", "clear_indices", "clone", "compact", "compact!", "compare_by_identity", "compare_by_identity?", "compute_indices_bytesize", "delete", "delete_entry", "delete_entry_and_update_counts", "delete_impl", "delete_linear_scan", "dig", "dig?", "do_compaction", "double_indices_size", "dup", "each", "each_entry_with_index", "each_key", "each_value", "empty?", "entries", "entries_capacity", "entries_full?", "entries_size", "entry_matches?", "fetch", "find_entry", "find_entry_with_index", "find_entry_with_index_linear_scan", "first_entry?", "first_key", "first_key?", "first_value", "first_value?", "fit_in_indices", "get_entry", "get_index", "has_key?", "has_value?", "hash", "indices_malloc_size", "indices_size", "initialize", "initialize_clone", "initialize_clone_entries", "initialize_compare_by_identity", "initialize_copy_non_entries_vars", "initialize_default_block", "initialize_dup", "initialize_dup_entries", "inspect", "invert", "key_for", "key_for?", "key_hash", "keys", "last_entry?", "last_key", "last_key?", "last_value", "last_value?", "malloc_entries", "malloc_indices", "merge", "merge!", "merge_into!", "next_index", "pretty_print", "proper_subset_of?", "proper_superset_of?", "put", "realloc_entries", "realloc_indices", "rehash", "reject", "reject!", "resize", "select", "select!", "set_entry", "set_index", "shift", "shift?", "size", "subset_of?", "superset_of?", "to_a", "to_a_impl", "to_h", "to_s", "transform_keys", "transform_values", "transform_values!", "update", "update_linear_scan", "upsert", "values", "values_at"]
IO.methods # => ["<<", "check_open", "close", "closed?", "decoder", "each_byte", "each_char", "each_line", "encoder", "encoding", "flush", "getb_to_end", "gets", "gets_peek", "gets_slow", "gets_to_end", "has_non_utf8_encoding?", "peek", "peek_or_read_utf8", "peek_or_read_utf8_masked", "pos", "pos=", "print", "printf", "puts", "read", "read_at", "read_byte", "read_bytes", "read_char", "read_char_with_bytesize", "read_fully", "read_fully?", "read_line", "read_string", "read_utf8", "read_utf8_byte", "rewind", "seek", "set_encoding", "skip", "skip_to_end", "tell", "tty?", "utf8_encoding?", "write", "write_byte", "write_bytes", "write_string", "write_utf8"]
File.methods # => ["delete", "initialize", "inspect", "path", "read_at", "size", "truncate"]
Mutex.methods # => ["initialize", "lock", "lock_slow", "synchronize", "try_lock", "unlock"]
PrettyPrint.methods # => ["break_outmost_groups", "breakable", "comma", "current_group", "fill_breakable", "flush", "group", "group_queue", "group_sub", "indent", "initialize", "list", "nest", "newline", "surround", "text"]
Process.methods # => ["channel", "close", "close_io", "copy_io", "ensure_channel", "error", "error?", "exists?", "finalize", "initialize", "input", "input?", "output", "output?", "pid", "signal", "stdio_to_fd", "terminate", "terminated?", "wait"]
Regex.methods # => ["+", "==", "===", "=~", "capture_count", "clone", "dup", "finalize", "hash", "initialize", "inspect", "internal_matches?", "match", "match_at_byte_index", "matches?", "matches_at_byte_index?", "name_table", "options", "source", "to_s"]
String.methods # => ["%", "*", "+", "<=>", "==", "=~", "[]", "[]?", "ascii_only?", "blank?", "byte_at", "byte_at?", "byte_delete_at", "byte_index", "byte_index_to_char_index", "byte_slice", "byte_slice?", "bytes", "bytesize", "calc_excess_left", "calc_excess_right", "camelcase", "capitalize", "center", "char_at", "char_bytesize_at", "char_index_to_byte_index", "chars", "check_no_null_byte", "chomp", "clone", "codepoint_at", "codepoints", "compare", "count", "delete", "delete_at", "downcase", "dump", "dump_char", "dump_hex", "dump_or_inspect", "dump_or_inspect_char", "dump_or_inspect_unquoted", "dump_unquoted", "dup", "each_byte", "each_byte_index_and_char_index", "each_char", "each_char_with_index", "each_codepoint", "each_grapheme", "each_grapheme_boundary", "each_line", "empty?", "encode", "ends_with?", "find_start_and_end", "grapheme_size", "graphemes", "gsub", "gsub_append", "gsub_ascii_char", "has_back_references?", "hash", "hexbytes", "hexbytes?", "includes?", "index", "insert", "insert_impl", "inspect", "inspect_char", "inspect_unquoted", "just", "lchop", "lchop?", "lines", "ljust", "lstrip", "match", "matches?", "partition", "presence", "pretty_print", "rchop", "rchop?", "remove_excess", "remove_excess_left", "remove_excess_right", "reverse", "rindex", "rjust", "rpartition", "rstrip", "scan", "scan_backreferences", "scrub", "single_byte_optimizable?", "size", "size_known?", "split", "split_by_empty_separator", "split_single_byte", "squeeze", "starts_with?", "strip", "sub", "sub_append", "sub_index", "sub_range", "succ", "titleize", "to_f", "to_f32", "to_f32?", "to_f64", "to_f64?", "to_f?", "to_f_impl", "to_i", "to_i128", "to_i128?", "to_i16", "to_i16?", "to_i32", "to_i32?", "to_i64", "to_i64?", "to_i8", "to_i8?", "to_i?", "to_s", "to_slice", "to_u128", "to_u128?", "to_u16", "to_u16?", "to_u32", "to_u32?", "to_u64", "to_u64?", "to_u8", "to_u8?", "to_unsafe", "to_unsigned_info", "to_utf16", "tr", "underscore", "unicode_delete_at", "unsafe_byte_at", "unsafe_byte_slice", "unsafe_byte_slice_string", "upcase", "valid_encoding?"]
Thread.methods # => ["detach", "event_base", "gc_thread_handler", "gc_thread_handler=", "initialize", "join", "main_fiber", "next", "next=", "previous", "previous=", "scheduler", "stack_address", "start", "to_unsafe"]
Bool.methods # => ["!=", "&", "==", "^", "clone", "hash", "to_s", "to_unsafe", "|"]
Int32.methods # => ["!=", "&", "&*", "&+", "&-", "*", "+", "-", "/", "<", "<=", "==", ">", ">=", "^", "clone", "leading_zeros_count", "popcount", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trailing_zeros_count", "unsafe_chr", "unsafe_div", "unsafe_mod", "unsafe_shl", "unsafe_shr", "|"]
Float64.methods # => ["!=", "*", "**", "+", "-", "/", "<", "<=", "==", ">", ">=", "ceil", "clone", "fdiv", "floor", "next_float", "prev_float", "round_away", "round_even", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_s", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trunc"]
Proc.methods # => ["==", "===", "arity", "call", "clone", "closure?", "closure_data", "hash", "internal_representation", "partial", "pointer", "to_s"]</syntaxhighlight>
== 脚註 ==
<references />
== 外部リンク ==
* [https://crystal-lang.org/ The Crystal Programming Language] {{---}} 公式サイト
** [https://crystal-lang.org/api/1.5.0/ Crystal 1.5.0 リファレンス]
** [https://play.crystal-lang.org/#/cr Compile & run code in Crystal] {{---}} playground
[[Category:Crystal|*]]
[[Category:プログラミング言語]]
{{NDC|007.64}}
8dlqft9yrtlu7faa0g9972cqwogckbh
205809
205796
2022-07-25T03:22:35Z
Ef3
694
/* クラスのメソッド一覧 */ style="overflow: scroll;height:7em"
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Crystal (プログラミング言語)}}
本書は、[[w:Crystal (プログラミング言語)|Crystal]]のチュートリアルです。
'''Crystal'''は、Ary Borenszweig、Juan Wajnerman、Brian Cardiffと300人以上の貢献者によって設計・開発された[汎用オブジェクト指向プログラミング言語です<ref>{{Cite web
|url=https://github.com/crystal-lang/crystal/graphs/contributors
|title=Contributors
|accessdate=2022-07-18
|website=github.com
}}</ref>。[[Ruby]] にヒントを得た構文を持ち、静的型チェックを備えた [[コンパイル型言語]]ですが、変数やメソッドの引数の型は一般には不要です。型は高度なグローバル[[型推論]]アルゴリズムによって解決される。<ref>{{Cite web
|url=http://crystal-lang.org/2013/09/23/type-inference-part-1.html
|title=Type inference part 1
|last=Brian J.
|first=Cardiff
|date=2013-09-09
|accessdate=2022-07-18
|website=crystal-lang.org
}}</ref>Crystalは[[Apache License]]バージョン2.0のもと、FOSSとしてリリースされています。
__TOC__
== Hello, World! ==
他の多くのチュートリアルがそうであるように、
私たちもまずはCrystalの世界にあいさつすることから始めましょう。
Rubyとの比較も兼ねて、[[Ruby#Hello, World!]]をそのまま実行してみます。
''hello.cr''というファイルを作り、次のように書いて保存して下さい<ref>Crystalのソースファイルの拡張子は''.cr'' です</ref>。
;hello.cr:<syntaxhighlight lang=Crystal>
puts 'Hello, World!'
</syntaxhighlight>
;コマンドラインでの操作:<syntaxhighlight lang="console">
% cat hello.cr
puts 'Hello, World!'
% crystal hello.cr
In hello.cr:1:6
1 | puts 'Hello, World!'
^
Error: unterminated char literal, use double quotes for strings
% sed -i -e "s@'@Q@g" -e 's@Q@"@g' hello.cr
% cat hello.cr
puts "Hello, World!"
% crystal hello.cr
Hello, World!
</syntaxhighlight>
この1行のスクリプトは、メソッド<code>puts</code> に文字リテラル<code>"Hello, World!"</code>を渡し呼出しています。
このプログラムは、[[Ruby#Hello, World!]]と同じですが、Crystalでは文字列リテラルは <code>"…"</code> で囲うのでそれだけ変更しました。
== プログラミング環境 ==
Crystalのプログラムを作り、コンパイル・実装するには、「オンライン実行環境を使う」・「エディト・コンパイル・実行環境を用意してそれを使う」の2通りの方法があります。
=== オンライン実行環境 ===
公式のオンライン実行環境、 https://play.crystal-lang.org/ があります。
まずは、これを使って本書に例示されているコードを実行してみることをお勧めします。
=== エディト・コンパイル・実行環境 ===
エディタについては本書では触れませんが、プログラミング時間の大半はエディタの操作に費やされるため、良いエディタを選択することが重要です。
Crystal の言語処理系は、 https://crystal-lang.org/install/ から入手します。
自分の、OSやGNU/Linuxであればディストリビューションに合わせてインストールしてください。
また、FreeBSDのように crystal と shards が別パッケージとなっていることもあるので、その場合は shards も追加インストールします。
多くの場合、インストールされた、 crystal はスタティック リンクされているので、ダイナミック リンク版の crystal を入手するには、スタティック リンク版の実行ファイルとソースコードを入手し、スタティック リンク版でソースから crystal をコンパイル・インストールする必要があります。
=== crystal コマンド ===
crystal コマンドは Crystal のコンパイラであると同時に、ビルドツールなどを含んだツールチェインです(プログラミング言語のCrystalは、先頭を大文字、コマンドのcrystalは、先頭を小文字にして区別します)。
[TODO: コマンドラインツール crystal の解説。 crystal ファイル名 は crystal run ファイル名 の短縮形で、インタープリタ的な実行…ではなく、内部ビルドツールでコンパイル・実行を行う]
== Ruby との違い ==
Crystalは、Rubyに触発された構文を持つものの、Rubyとの互換性をゴールに定めては'''いません'''。
このため、細部を見ると仕様に差異があり、Rubyのソースコードをcrystalに掛けても前節の 'Hello World' の様にコンパイルに失敗することがあります。
また、コンパイルできても実行結果に違いが出ることがあります。
ここでは、Ruby との違いについて実際のコードと双方の結果を比較することで、差異についての理解を深めていきます。
=== 整数型の特性 ===
;大きな整数:<syntaxhighlight lang=Crystal>
p 2 ** 999
p (2 ** 999).class
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
Integer
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
Unhandled exception: Arithmetic overflow (OverflowError)
from /usr/local/share/crystal/share/crystal/src/int.cr:295:9 in '**'
from pow.cr:1:1 in '__crystal_main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:101:7 in 'main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:127:3 in 'main'
from /usr/local/lib64/libc.so.6 in '__libc_start_main'
from /usr/local/.cache/crystal/crystal-run-pow.tmp in '_start'
from ???
</syntaxhighlight>
: Ruby の整数は、桁あふれが起こると自動的に多倍長整数に型変換されるので、継ぎ目なしに大きな数を扱うアルゴルズムが使えます。
: Crystal の整数は、固定長です(大きさについては[[#リテラルと型|後述]])。なので大きな答えになる式を評価すると桁あふれが生じます。桁あふれが生じますが、C言語のように寡黙に処理を続けるのではなく、実行時に例外(OverflowError)が上がるので、例外を捕捉し然るべき処置を施すことが可能です。
==== BigInt ====
<code>big</code> を <code>require</code> すると <code>BigInt</code> が使えるようになります。
;BigInt:<syntaxhighlight lang=Crystal>
require "big"
p BigInt.new(2) ** 999
p (BigInt.new(2) ** 999).class
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
BigInt
</syntaxhighlight>
: BigIntはプリミティブではなので、リテラル表現はありません。また、
::<syntaxhighlight lang=Crystal>
n : BigInt = 2
</syntaxhighlight>
::<syntaxhighlight lang=console>
Error: type must be BigInt, not Int32
</syntaxhighlight>
:: のように型アノテーションすることも出来ません。
=== リテラルと型 ===
;様々なリテラルと型:<syntaxhighlight lang=Crystal>
[nil, false, true, 42, 2.73, 'Q', "string", [1,2,3], {a:1, b:2}].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
[nil, NilClass]
[false, FalseClass]
[true, TrueClass]
[42, Integer]
[2.73, Float]
["Q", String]
["string", String]
[[1, 2, 3], Array]
[{:a=>1, :b=>2}, Hash]
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
[nil, Nil]
[false, Bool]
[true, Bool]
[42, Int32]
[2.73, Float64]
['Q', Char]
["string", String]
[[1, 2, 3], Array(Int32)]
[{a: 1, b: 2}, NamedTuple(a: Int32, b: Int32)]
</syntaxhighlight>
: Crystal の整数は Int32、浮動小数点数は Float64 です。
;サイズを指定した数リテラル:<syntaxhighlight lang=Crystal>
[1_i64, 2_u32, 3_u64, 4_i32, 5_i16, 6_u8, 7_i128, 8_u128, 3.14_f32, 1.44_f64].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;ruby:Rubyでは、サーフィックスの付いた数値リテラルは無効
;crystalの実行結果:<syntaxhighlight lang="console">
[1, Int64]
[2, UInt32]
[3, UInt64]
[4, Int32]
[5, Int16]
[6, UInt8]
[7, Int128]
[8, UInt128]
[3.14, Float32]
[1.44, Float64]
</syntaxhighlight>
: Crystal では、数値リテラルに _ で始まるサーフィックスを付け { i:符号付き整数, u:符号なし整数, f:浮動小数点数 } と { 8,16,32,64,128 } のビット幅の組合せです<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/literals/ Literals]</ref>。
=== for式がない ===
Crystal には、Ruby にはある for式がありません。
;Rubyのfor式の構文:<syntaxhighlight lang="ruby">
for 変数 in コレクション
文
end
</syntaxhighlight>
:コレクションは Range, Array, Hash など内部構造を持つオブジェクトです。
:for式は、最後に評価した値を返すので、for'''式'''です。
;for式のeachメソッドによる置換え:<syntaxhighlight lang="ruby">
for x in [ 2, 3, 5, 7, 11 ] do
p x
end
# ↓
[ 2, 3, 5, 7, 11 ].each do | x |
p x
end
</syntaxhighlight>
: の様にコレクションの each メソッドで置換え可能なので、Rubyからの移植でも小規模な書換えで済みます<ref>[https://github.com/crystal-lang/crystal/issues/830 "For" Loop support #830]</ref>(後述のマクロで実装できないかと思いましたが、いまのところ無理のようです)。
また loop 式もありませんが while true; … end で間に合います。Ruby では while 式の条件の次に do が置けますが、Crystal では置けません。
=== eval()がない ===
Crystal には eval() はありません。
Crystalはコンパイル型言語ですので、無理もないことです。
もし、Crystal で eval() を実装しようとすると、Common Lisp の様にインタープリターを丸ごとランタイムに含む必要があります。
これはリーズナブルな選択ではありません。
Crystal では、eval() が必要なケースに(限定的ですが)マクロを使うことで実現出来る可能性があります。
=== マクロ ===
Crystalには、Rubyにはないマクロがあります<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/macros/ Macros - Crystal]</ref>。Rubyは実行時にすべてのオブジェクトにアクセス出来て、メソッド生やし放題なのでマクロは必要ありませんが、Crystalはコンパイル時に型やメソッドを確定する必要があり、特にメソッドジェネレターとしてのマクロにニーズがあります。また、テンプレート言語的なマクロなので、環境変数による条件分岐や、コンテナを渡し繰返し処理する構文もあります(面白いことにマクロには for 文があり、反対にマクロの中では、eachメソッドは使えません)。マクロには <code><nowiki>{{</nowiki>attr.id}}</code> の様にASTへのアクセス手順が用意されており、半ば言語を拡張するようなアプローチを取ることも出来ます。
[TODO:ASTについての解説;コラム向き?]
;マクロを使ったattr_accessorのイミュレーション:<syntaxhighlight lang=crystal>
class Point
def initialize(@x : Int32, @y : Int32)
end
# macro定義
macro attr_accessor(*attrs)
{% for attr in attrs %}
def {{attr.id}}() @{{attr.id}} end
def {{attr.id}}=(var) @{{attr.id}} = var end
{% end %}
end
# macro呼出し
attr_accessor :x, :y
end
pt = Point.new(20, 30)
p [pt.x, pt.y]
t = pt.x
pt.x = pt.y
pt.y = t
p [pt.x, pt.y]
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
[20, 30]
[30, 20]
</syntaxhighlight>
: Ruby には、attr_accessor と言う「クラスのメンバーのアクセサーを自動生成するメソッド」がありますが、Crystalにはないようなので、マクロで実装しました。
:: attr_accessor :name からは
::<syntaxhighlight lang=ruby>
def name() @name end
def name=(val) @name = val end
</syntaxhighlight>相当のコードが生成されます。
[TODO:マクロの機能と構文の説明 *の付いた引数、 <nowiki>{{</nowiki>引数}}、{% … %} 構文]
==== マクロ p! ====
メソッド p は、与えられた「式」の inspaect() の返す値を puts しますが、マクロ p! は、それに先んじて(評価前の)「式」を表示します<ref>[https://crystal-lang.org/api/1.5.0/Crystal/Macros.html#p%21%28%2Aexpressions%29%3ANop-instance-method def p!(*expressions) : Nop]</ref>。
;p!の例:<syntaxhighlight lang=crystal>
x, y = true, false
p! x,y,x && y, x || y, x ^ y, !x, x != y, x == y
ary = [ 1, 2, 3 ]
p! ary
p! ary.map(&. << 1)
p! ary.map(&.to_f)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
x # => true
y # => false
x && y # => false
x || y # => true
x ^ y # => true
!x # => false
x != y # => true
x == y # => false
ary # => [1, 2, 3]
ary.map(&.<<(1)) # => [2, 4, 6]
ary.map(&.to_f) # => [1.0, 2.0, 3.0]
</syntaxhighlight>
===== 入れ子のp! =====
マクロ p! は入れ子に出来ます。また、一旦ASTに変換してから再度ソースコードに変換するので、等価な別の構文に変換されることがあります。
;入れ子のp!:<syntaxhighlight lang=crystal>
p! (
100.times{|i|
p! i
break i if i > 12
}
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(100.times do |i|
p!(i)
if i > 12
break i
end
end) # => i
# => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
i # => 6
i # => 7
i # => 8
i # => 9
i # => 10
i # => 11
i # => 12
i # => 13
13
</syntaxhighlight>
=== クラス ===
==== シンプルなクラス ====
;シンプルなクラス:<syntaxhighlight lang=crystal highlight="2" line>
class Hello
def initialize(@name : String = "World")
end
def greeting
puts "Hello #{@name}!"
end
end
hello = Hello.new()
hello.greeting
universe = Hello.new("Universe")
universe.greeting
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Hello World!
Hello Universe!
</syntaxhighlight>
:;初期化メソッド
:: <syntaxhighlight lang=crystal line start=4>
def initialize(@name : String = "World")
end
</syntaxhighlight>
::Rubyであれば
:: <syntaxhighlight lang=ruby line start=4>
def initialize(name = "World")
@name = name
end
</syntaxhighlight>
::とするところですが、Crystalでは、型アノテーション <code> : String</code> を使い、引数の型を限定しました。
::また、(@ 付きの)アトリビュート名を仮引数にすると、そのままアトリビュート(a.k.a. インスタンス変数)に仮引数が代入されます。
::これは、C++のコンストラクターのメンバー初期化リストと同じアイディアですが、Crystalではインスタンス変数に @ が前置されるので、仮引数に @ が出現すればインスタンス変数の初期値だと自明で、聡明な選択です。
==== 都市間の大圏距離 ====
[[Ruby#ユーザー定義クラス]]の都市間の大圏距離を求めるメソッドを追加した例を、Crystalに移植しました。
;都市間の大圏距離:<syntaxhighlight lang=crystal highlight=”2,7,12” line>
class GeoCoord
getter :longitude, :latitude
def initialize(@longitude : Float64, @latitude : Float64)
end
def to_s(io)
ew, ns = "東経", "北緯"
long, lat = @longitude, @latitude
ew, long = "西経", -long if long < 0.0
ns, lat = "南緯", -lat if lat < 0.0
io << "(#{ew}: #{long}, #{ns}: #{lat})"
end # https://github.com/crystal-lang/crystal/issues/259
def distance(other)
i, r = Math::PI / 180, 6371.008
Math.acos(Math.sin(@latitude*i) * Math.sin(other.latitude * i) +
Math.cos(@latitude*i) * Math.cos(other.latitude * i) * Math.cos(@longitude * i - other.longitude * i)) * r
end
end
# メソッドの先頭を大文字に出来ないのでクラス名のメソッドは作ることが出来ない
# def GeoCoord(lng : Float64, lat : Float64)
# GeoCoord.new(lng, lat)
# end
Sites = {
"東京駅": GeoCoord.new(139.7673068, 35.6809591),
"シドニー・オペラハウス": GeoCoord.new(151.215278, -33.856778),
"グリニッジ天文台": GeoCoord.new(-0.0014, 51.4778),
}
Sites.each { |name, gc|
puts "#{name}: #{gc}"
}
puts ""
keys, len = Sites.keys, Sites.size
keys.each_with_index { |x, i|
y = keys[(i + 1) % len]
puts "#{x} ⇔ #{y}: #{Sites[x].distance(Sites[y])} [km]"
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
東京駅: (東経: 139.7673068, 北緯: 35.6809591)
シドニー・オペラハウス: (東経: 151.215278, 南緯: 33.856778)
グリニッジ天文台: (西経: 0.0014, 北緯: 51.4778)
東京駅 ⇔ シドニー・オペラハウス: 7823.269299386704 [km]
シドニー・オペラハウス ⇔ グリニッジ天文台: 16987.2708377249 [km]
グリニッジ天文台 ⇔ 東京駅: 9560.546566490015 [km]
</syntaxhighlight>
:Crystal には、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> はありませんが、標準ライブラリーのマクロに <syntaxhighlight lang=crystal inline> getter </syntaxhighlight>があるので
:: <syntaxhighlight lang=crystal line start=2>
getter :longitude, :latitude
</syntaxhighlight>
::としました。
::将来、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> が実装される可能性はありますが、姉妹品の<syntaxhighlight lang=crystal inline> setter </syntaxhighlight> との併用が下位互換性を考えると確実です。
: to_s は、Ruby ならば
:: <syntaxhighlight lang=ruby line start=7>
def to_s()
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
"(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
:: ですが、Crystalでは追加の引数 <var>io</var> が必要で
:: <syntaxhighlight lang=ruby line start=7>
def to_s(io)
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
io << "(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
: Ruby にはクラス名と同じ名前のメソッドで .new を呼出す文化があるのですが、Crystalはメソッドの先頭を大文字に出来ないので、これは見送りました。
==== 包含と継承 ====
[[JavaScript/クラス#包含と継承]]を、Rubyに移植した[[Ruby#包含と継承]]を、Crystalに移植しました。
;包含と継承の例:<syntaxhighlight lang=crystal line>
class Point
def initialize(@x = 0, @y = 0)
end
def inspect(io)
io << "x:#{@x}, y:#{@y}"
end
def move(dx = 0, dy = 0)
@x, @y = @x + dx, @y + dy
self
end
end
class Shape
def initialize(x = 0, y = 0)
@location = Point.new(x, y)
end
def inspect(io)
@location.inspect(io)
end
def move(x, y)
@location.move(x, y)
self
end
end
class Rectangle < Shape
def initialize(x = 0, y = 0, @width = 0, @height = 0)
super(x, y)
end
def inspect(io)
super(io)
io << ", width:#{@width}, height:#{@height}"
end
end
rct = Rectangle.new(12, 32, 100, 50)
p! rct,
rct.is_a?(Rectangle),
rct.is_a?(Shape),
rct.is_a?(Point),
rct.move(11, 21)
(END)</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
rct # => x:12, y:32, width:100, height:50
rct.is_a?(Rectangle) # => true
rct.is_a?(Shape) # => true
rct.is_a?(Point) # => false
rct.move(11, 21) # => x:23, y:53, width:100, height:50
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy inclusion-and-inheritance.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (16 bytes)
. @location : Point (8 bytes)
|
+- class Rectangle (24 bytes)
@width : Int32 (4 bytes)
@height : Int32 (4 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
===== superclass と subclasses =====
Crystal には、RubyのClassにあるメソッド superclass と subclasses がないので、マクロで実装しました。
;superclass と subclasses:<syntaxhighlight lang=crystal line>
class Class
def self.superclass
{{ @type.superclass }}
end
def self.subclasses : Array(self.class)
{{ @type.subclasses }}.map(&.as(self.class))
end
def self.all_subclasses : Array(self.class)
{% begin %}
[{{ @type.all_subclasses.join(",").id }}] of self.class
{% end %}
end
end
class A end
class AA < A end
class AAA < AA end
class AAB < AA end
class AB < A end
p! A,
A.subclasses,
A.all_subclasses,
AAA.superclass,
A.superclass
c = AAA
while !c.is_a? Nil
p! c.superclass
c = c.superclass
end</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
A # => A
A.subclasses # => [AA, AB]
A.all_subclasses # => [AA, AAA, AAB, AB]
AAA.superclass # => AA
A.superclass # => Reference
c.superclass # => AA
c.superclass # => A
c.superclass # => Reference
c.superclass # => Object
c.superclass # => nil
</syntaxhighlight>
==== 抽象クラス ====
[[Java/抽象クラス]]を、Crystalに移植しました。
;抽象クラスの宣言:<syntaxhighlight lang=Java>
abstract class クラス名
#
end
</syntaxhighlight>
: このクラス名は、 .new でインスタンス化出来ません。
:: Error: can't instantiate abstract class クラス名
: となります。
:インスタンス化することは出来ませんが、抽象クラスを別のクラスが継承する事は出来ます。
:また、抽象クラスを <code>super()</code> を使うことでメソッドを呼び出せるので、抽象メソッドではないメソッド(具象メソッド)を持つことも、インスタンス変数も持つことも出来ます。
:'''抽象クラスの例'''では、Shapeのinitializeメソッドが抽象クラスの具象メソッドとなっています。
;抽象メソッドの宣言:<syntaxhighlight lang=Java>
abstract def メソッド名
</syntaxhighlight>
: 派生先のクラスで、「メソッド名」を定義(def)し忘れると
:: Error: abstract `def クラス名#メソッド名()` must be implemented by クラス名
: となります
;抽象クラスの例:<syntaxhighlight lang=crystal line>
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
class Recrangle < Shape
def initialize(x, y, @w = 0.0, @h = 0.0)
super(x, y)
end
def to_s(io)
io << "Rectanle(#{@x}, #{@y}, #{@w}, #{@h})"
end
def area
@w * @h
end
end
class Circle < Shape
def initialize(x, y, @r = 0.0)
super(x, y)
end
def to_s(io)
io << "Circle(#{@x}, #{@y}, #{@r})"
end
def area
3.1425926536 * @r * @r
end
end
shapes = [
Square.new(5.0, 10.0, 15.0),
Recrangle.new(13.0, 23.0, 20.0, 10.0),
Circle.new(3.0, 2.0, 20.0),
] of Shape
shapes.each do |shape|
puts("#{shape}: #{shape.area}")
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Square(5.0, 10.0, 15.0): 225.0
Rectanle(13.0, 23.0, 20.0, 10.0): 200.0
Circle(3.0, 2.0, 20.0): 1257.03706144
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy abstract.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (24 bytes)
. @x : Float64 (8 bytes)
. @y : Float64 (8 bytes)
|
+- class Circle (32 bytes)
| @r : Float64 (8 bytes)
|
+- class Recrangle (40 bytes)
| @w : Float64 (8 bytes)
| @h : Float64 (8 bytes)
|
+- class Square (32 bytes)
@wh : Float64 (8 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
: 「包含と継承の例」と比べると、ShapeとRectangleが同じ階層にあることがわかると思います。
[TODO:virtual class::いい例がない]
== キーワード ==
Crystalのキーワード( ''keywords'' ) は、以下の通り。
<code>abstract</code> <code>alias</code> <code>as</code> <code>asm</code> <code>begin</code> <code>break</code> <code>case</code> <code>class</code> <code>def</code> <code>do</code> <code>else</code> <code>elsif</code> <code>end</code> <code>ensure</code> <code>enum</code> <code>extend</code> <code>for</code> <code>fun</code> <code>if</code> <code>include</code> <code>instance_sizeof</code> <code>lib</code> <code>macro</code> <code>module</code> <code>next</code> <code>of</code> <code>out</code> <code>pointerof</code> <code>private</code> <code>protected</code> <code>rescue</code> <code>return</code> <code>require</code> <code>select</code> <code>sizeof</code> <code>struct</code> <code>super</code> <code>then</code> <code>type</code> <code>typeof</code> <code>uninitialized</code> <code>union</code> <code>unless</code> <code>until</code> <code>when</code> <code>while</code> <code>with</code> <code>yield</code>
<!--
<code>__DIR__</code> <code>__END_LINE__</code> <code>__FILE__</code> <code>__LINE__</code>
-->
== 演算子 ==
Crystalは、1つ、2つ、または3つのオペランドを持つ数多くの演算子をサポートしています<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/operators.html Operators]access-date:2022-07-22</ref>。
演算子式は、実際にはメソッド呼び出しとしてパースされます。例えば、<code>a + b</code> は <code>a.+(b)</code> と意味的に同じで、引数 b を持つ a のメソッド + を呼び出すことになります。
{| class="wikitable"
|+ 演算子の優先度
!種類
!演算子
|-
|インデックス アクセサー
|<code>[]</code>, <code>[]?</code>
|-
|単項
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>, <code>!</code>, <code>~</code>
|-
|指数
|<code>**</code>, <code>&**</code>
|-
|乗除
|<code>*</code>, <code>&*</code>, <code>/</code>, <code>//</code>, <code>%</code>
|-
|加減
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>
|-
|シフト
|<code><<</code>, <code>>></code>
|-
|ビット間 AND
|<code>&</code>
|-
|ビット間 OR/XOR
|<code><nowiki>|</nowiki></code>,<code>^</code>
|-
|等値
|<code>==</code>, <code>!=</code>, <code>=~</code>, <code>!~</code>, <code>===</code>
|-
|比較
|<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>, <code><=></code>
|-
|論理 AND
|<code>&&</code>
|-
|論理 OR
|<code><nowiki>||</nowiki></code>
|-
|Range
|<code>..</code>, <code>...</code>
|-
|条件
|<code>?:</code>
|-
|代入
|<code>=</code>, <code>[]=</code>, <code>+=</code>, <code>&+=</code>, <code>-=</code>, <code>&-=</code>, <code>*=</code>, <code>&*=</code>, <code>/=</code>, <code>//=</code>, <code>%=</code>, <code><nowiki>|=</nowiki></code>, <code>&=</code>,<code>^=</code>,<code>**=</code>,<code><<=</code>,<code>>>=</code>, <code><nowiki>||=</nowiki></code>, <code>&&=</code>
|-
|スプラット
|<code>*</code>, <code>**</code>
|}
== 制御構造 ==
'''[[w:制御構造|制御構造]]'''(せいぎょこうぞう、''control flow'')とは、「順次」「分岐」「反復」という基本的な処理のことを言います。
{{コラム|Crystalの真理値|2=
制御構造は「条件式」が真であるか偽であるかによって分岐や反復の振る舞いが変わります。
では「条件式」が真・偽はどの様に決まるのでしょう?
Crystalでは <code>false</code> あるいは <code>nil</code> であると偽、それ以外が真です。
なので <code>0</code> も <code>[]</code>(空のArray) も <code>{}</code>(空のNamedTuple)も真です。
}}
=== 条件分岐 ===
Crystalの条件分岐には、[[#if|if]], [[#until|until]] と [[#case|case]]の3つの構文があります。
==== if ====
'''[[w:if|if]]'''は条件式によって実行・否を切り替える構造構文で、評価した式の値を返すので条件演算子でもあります。
;ifの例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
if a < 0
puts "minus"
elsif a > 0
puts "plus"
elsif a == 0
puts "zero"
else
puts a
end
p! (
if a < 0
"minus"
elsif a > 0
"plus"
elsif a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(if a < 0
"minus"
else
if a > 0
"plus"
else
if a == 0
"zero"
else
a
end
end
end) # => NaN
</syntaxhighlight>
:; elsif節:ifは、オプショナルな elsif 節を設け、条件式が偽であった時に別の条件に合致した処理を実行させることが出来ます。
:; else節:ifは、オプショナルな else 節を設け、条件式が偽であった時に処理を実行させることが出来ます。
: ifは値を返すので、メソッドの実引数に使うことが出来ますし、代入演算の右辺にも使えます。
==== 後置のif ====
Crystalには、RubyやPerlのような後置のifがあります。
;後置のifの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" if n == 0
puts "nは1" if n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは0
</syntaxhighlight>
==== unless====
'''unless'''(アンレス)は条件式によって実行・否を切り替える構造構文ですが、ifとは条件式に対する挙動が逆です。
;unless文の例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
unless a == 0
puts "Non-zero"
else
puts a
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Non-zero
</syntaxhighlight>
:; else節 : unless文は、オプショナルな else 節を設け、条件式が真であった時に処理を実行させることが出来ます。
::また、unless文は elsif 節は持てません。
==== 後置のunless ====
Crystalには、RubyやPerlのような後置のunlessがあります。
;後置のunlessの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" unless n == 0
puts "nは1" unless n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは1ではない
</syntaxhighlight>
==== case ====
caseは、複数の条件式によって処理を降る分ける用途の為に用意されています。
;caseの例:<syntaxhighlight lang=crystal line>
n = 2
case n
when 1
puts "one"
when 2
puts "two"
when 3
puts "three"
else
puts "other"
end
p! (
case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
two
(case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end) # => "two"</syntaxhighlight>
:C言語系のswitch文に慣れた人はbreakがないことに気がつくと思います。Crystalのcaseはfall throughしませんし、fall throughさせる方法もありません。
===== when節が定数でなく式を受付けます =====
[[#if|if]]を使ったコードをcaseに書き換えてみましょう。
;case の式の省略:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
case
when a < 0
puts "minus"
when a > 0
puts "plus"
when a == 0
puts "zero"
else
puts a
end
p! (
case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end) # => NaN
</syntaxhighlight>
このコードは when 節の式の値とcaseの式を <code>===</code> で比較し、最初に一致した when に対応する式が実行される事を利用しています。
===== 型による分岐 =====
when 節が式ではなく型であった場合、caseの式を <code>is_a?</code> で評価し、最初に一致した when に対応する式が実行されます。
;型による分岐:<syntaxhighlight lang=crystal line>
p! 0.class,
0.is_a?(Object),
0.is_a?(Int32),
0.is_a?(Number),
0.is_a?(String)
case 0
when String
puts "String"
when Number
puts "Number"
when Int32
puts "Int32"
when Object
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0.class # => Int32
0.is_a?(Object) # => true
0.is_a?(Int32) # => true
0.is_a?(Number) # => true
0.is_a?(String) # => false
Number
</syntaxhighlight>
暗黙のオブジェクト構文を使うと
:<syntaxhighlight lang=crystal line>
case 0
when .is_a?(String)
puts "String"
when .is_a?(Number)
puts "Number"
when .is_a(Int32)
puts "Int32"
when .is_a(Object)
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
:と書くことが出来ます。
:: メソッドは、.is_a? に限定しないので、 .odd? .even? .include? など Bool を返すメソッドなら何でも使えます。
when に対応する式は、1つのことが珍しくないので、その場合は省略可能な then を補うと、1行で書けます。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
[TODO:タプルとダミー識別子 _ ]
===== 網羅性の検査 =====
when の代わりに in を使用すると、exhaustive case 式が作成されます。exhaustive case では、必要な in 条件を省略するとコンパイル時にエラーとなります。排他的論理和では、when 節と else 節を含むことはできません。
コンパイラは、以下の in 条件をサポートしています。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
caseの式がユニオンの場合、各要素型を条件として使用することができる。
;組合型チェック:<syntaxhighlight lang=crystal line>
var : ( Bool | Int32 | Float64 )?
var = 3.14
p! (
case var
in Bool then var ? 1 : 0
in Int32 then var
in Float64 then var.to_i
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
(case var
in Bool
var ? 1 : 0
in Int32
var
in Float64
var.to_i
end) # => 3
</syntaxhighlight>
[TODO:case in は enum にも使える]
[TODO:短絡評価 && || ]
=== 繰返し ===
Crystalには、他のプログラミング言語のような[[#繰返し構文|繰返し構文]]と、[[#イテレーターメソッド|イテレーターメソッド]]があります。
==== 繰返し構文 ====
Crystalの繰返し構文には、while と untilの2つがあります<ref>for も do-while も loop もありません。</ref>。
===== while =====
while(ホワイル)は条件が'''真'''である間、式を実行しつづけます。
;構文:<syntaxhighlight lang=crystal>
while 条件式
式1
式2
:
式n
end
</syntaxhighlight>
: Rubyと違い、条件式の後ろに <code>do</code> をつけることは出来ません。
;while文のコード例:<syntaxhighlight lang=crystal line>
i = 0
p! (
while i < 10
p! i
i += 1
break i if i > 5
end
)
</syntaxhighlight>
: 2行目の <code>i < 5</code>が真の間、次の2行を繰返します。
: 4行目の <code>i += 1</code> は <code>i = i + 1</code> の構文糖
;実行結果:<syntaxhighlight lang="text">
(while i < 10
p!(i)
i = i + 1
if i > 5
break i
end
end)# =>
i # => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
6
</syntaxhighlight>
===== until =====
until(アンティル)は条件が'''偽'''である間、式を実行しつづけます。whileとは条件に対する挙動が逆です。
;構文:<syntaxhighlight lang=crystal>
until 条件式 [ do ]
文1
文2
:
文n
end
</syntaxhighlight>
: <code>do</code> は省略できます。
;untilのコード例:<syntaxhighlight lang=crystal line>
i = 0
until i == 3
puts i
i += 1
end
</syntaxhighlight>
: 2行目の <code>i == 3</code>が偽の間、次の2行を繰返します。
;実行結果:<syntaxhighlight lang="text">
0
1
2
</syntaxhighlight>
===== for =====
Crystalにはforがありませんが、コレクションのイテレーションメソッドを使うことで繰返しを簡素に実現出来ます。
==== Rangeオブジェクト ====
Rangeオブジェクトは、整数の区間を表し範囲演算子 <code>開始 ... 終了</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
rng = 1..3
puts rng.class
rng.each do | n |
puts "#{n}番";
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Range(Int32, Int32)
1番
2番
3番
</syntaxhighlight>
==== Arrayオブジェクト ====
Arrayオブジェクトは、任意の Crystal オブジェクトを要素として持つことができます。
配列式<code>[要素1, 要素2, … 要素n]</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
animals = ["ネコ", "金魚", "ハムスター"]
puts animals.class
animals.each do | animal |
puts "動物 #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Array(String)
動物 ネコ
動物 金魚
動物 ハムスター
</syntaxhighlight>
==== NamedTupleオブジェクト ====
NamedTupleオブジェクトは、任意の Crystal オブジェクトをキーに、任意の Crystal オブジェクトを値に持つことができる連想配列です。
NamedTuple式<code>{キー1 => 値1, キー2 => 値2, キーn => 値n}</code> で生成します。
また、キーが Symbol の場合
NamedTuple式<code>{キー1: 値1, キー2: 値2, キーn: 値n}</code> で生成することが出来ます。
;コード:<syntaxhighlight lang=crystal>
animals = {cat: "ネコ", gold_fish: "金魚", hamster: "ハムスター"}
puts animals.class
animals.each do | en, animal |
puts "動物 #{en}: #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NamedTuple(cat: String, gold_fish: String, hamster: String)
動物 cat: ネコ
動物 gold_fish: 金魚
動物 hamster: ハムスター
</syntaxhighlight>
このように、Crystalではforがなくてもコレクションのメソッドで同様の処理を実現できます。
===== loop =====
loop、ありません。
while true で代用します。
;loopの代用コード例:<syntaxhighlight lang=crystal line>
i = 1
while true
puts "0b%b" % i
i <<= 1
break if i > 2**8
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0b1
0b10
0b100
0b1000
0b10000
0b100000
0b1000000
0b10000000
0b100000000
</syntaxhighlight>
:5行目の、<code>break if i > 2**8</code>でループを脱出するようにしています。この様に break や return あるいは例外が上がらないとループは永久に終わりません。
:このコードは、Crystalにはない do-while文を模倣する例にもなっています。
==== イテレーターメソッド ====
===== Integer#times =====
Integer#timesは与えられたブロックをオブジェクトの示す整数値回くりかえします。
:コード<syntaxhighlight lang=crystal>
3.times{ puts "Hello, world!" }
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello, world!
Hello, world!
Hello, world!
</syntaxhighlight>
;繰返したい処理が2行以上ある場合:<syntaxhighlight lang=crystal>
3.times {
puts "Hello"
puts "World"
puts ""
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello
World
Hello
World
Hello
World
</syntaxhighlight>
;ループ変数を使た例:<syntaxhighlight lang=crystal>
3.times do |i|
puts "#{i}の倍は#{2 * i}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0の倍は0
1の倍は2
2の倍は4
</syntaxhighlight>
;ブロックを伴わないtimesメソッド:<syntaxhighlight lang=crystal>
iter = 3.times
puts iter.class
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
# puts iter.next # `next': StopIteration: iteration reached an end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Int::TimesIterator(Int32)
iter.next # => 0
iter.next # => 1
iter.next # => 2
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
</syntaxhighlight>
: Integer#times にブロックを渡さないと、Int::TimesIterator([T])オブジェクトが返ります。
: Int::TimesIterator([T])オブジェクトは外部イテレーターと呼ばれnextメソッドで反復を行えます。
== メソッド ==
=== クラスのメソッド一覧 ===
Crystal には、Objectクラスにmethodsメソッドがないので、マクロで実装しました。
;RubyのObject#methods:<syntaxhighlight lang=ruby>
p Object.methods.sort,
Integer.methods.sort,
Float.methods.sort,
Array.methods.sort,
Range.methods.sort
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :sqrt, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :[], :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
</syntaxhighlight>
;Crystalに実装したmethodsマクロ:<syntaxhighlight lang=crystal>
class Object
macro methods
{{ @type.methods.map(&.name.stringify).sort.uniq }}
end
end
p! Object.methods,
Reference.methods,
Array.methods,
Box.methods,
Channel.methods,
Deque.methods,
Dir.methods,
Exception.methods,
ArgumentError.methods,
DivisionByZeroError.methods,
IndexError.methods,
InvalidByteSequenceError.methods,
Fiber.methods,
Hash.methods,
IO.methods,
File.methods,
Mutex.methods,
PrettyPrint.methods,
Process.methods,
Regex.methods,
String.methods,
Thread.methods,
Bool.methods,
Int32.methods,
Float64.methods,
Proc.methods
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
Object.methods # => ["!=", "!~", "==", "===", "=~", "class", "crystal_type_id", "dup", "hash", "in?", "inspect", "itself", "not_nil!", "pretty_inspect", "pretty_print", "tap", "to_s", "try", "unsafe_as"]
Reference.methods # => ["==", "dup", "exec_recursive", "exec_recursive_clone", "hash", "inspect", "object_id", "pretty_print", "same?", "to_s"]
Array.methods # => ["&", "*", "+", "-", "<<", "<=>", "==", "[]", "[]=", "[]?", "calculate_new_capacity", "check_needs_resize", "check_needs_resize_for_unshift", "clear", "clone", "compact", "compact!", "concat", "delete", "delete_at", "dup", "each_repeated_permutation", "fill", "first", "flatten", "increase_capacity", "increase_capacity_for_unshift", "index", "initialize", "insert", "inspect", "internal_delete", "last", "map", "map_with_index", "needs_resize?", "pop", "pop?", "pretty_print", "product", "push", "reject!", "remaining_capacity", "repeated_permutations", "replace", "reset_buffer_to_root_buffer", "resize_if_cant_insert", "resize_to_capacity", "resize_to_capacity_for_unshift", "reverse", "root_buffer", "rotate", "rotate!", "select!", "shift", "shift?", "shift_buffer_by", "shift_when_not_empty", "shuffle", "size", "size=", "skip", "sort", "sort!", "sort_by", "sort_by!", "to_a", "to_lookup_hash", "to_s", "to_unsafe", "to_unsafe_slice", "transpose", "truncate", "uniq", "uniq!", "unsafe_fetch", "unsafe_put", "unshift", "unstable_sort", "unstable_sort!", "unstable_sort_by", "unstable_sort_by!", "|"]
Box.methods # => ["initialize", "object"]
Channel.methods # => ["close", "closed?", "dequeue_receiver", "dequeue_sender", "initialize", "inspect", "pretty_print", "receive", "receive?", "receive_impl", "receive_internal", "receive_select_action", "receive_select_action?", "send", "send_internal", "send_select_action"]
Deque.methods # => ["+", "<<", "==", "buffer", "clear", "clone", "concat", "delete", "delete_at", "dup", "each", "halfs", "increase_capacity", "initialize", "insert", "inspect", "internal_delete", "pop", "pop?", "pretty_print", "push", "reject!", "rotate!", "select!", "shift", "shift?", "size", "size=", "to_s", "unsafe_fetch", "unsafe_put", "unshift"]
Dir.methods # => ["children", "close", "each", "each_child", "entries", "initialize", "inspect", "path", "pretty_print", "read", "rewind", "to_s"]
Exception.methods # => ["backtrace", "backtrace?", "callstack", "callstack=", "cause", "initialize", "inspect", "inspect_with_backtrace", "message", "to_s"]
ArgumentError.methods # => ["initialize"]
DivisionByZeroError.methods # => ["initialize"]
IndexError.methods # => ["initialize"]
InvalidByteSequenceError.methods # => ["initialize"]
Fiber.methods # => ["cancel_timeout", "dead?", "enqueue", "initialize", "inspect", "makecontext", "name", "name=", "next", "next=", "previous", "previous=", "push_gc_roots", "resumable?", "resume", "resume_event", "run", "running?", "stack_bottom", "stack_bottom=", "timeout", "timeout_event", "timeout_select_action", "timeout_select_action=", "to_s"]
Hash.methods # => ["==", "[]", "[]=", "[]?", "add_entry_and_increment_size", "clear", "clear_entries", "clear_impl", "clear_indices", "clone", "compact", "compact!", "compare_by_identity", "compare_by_identity?", "compute_indices_bytesize", "delete", "delete_entry", "delete_entry_and_update_counts", "delete_impl", "delete_linear_scan", "dig", "dig?", "do_compaction", "double_indices_size", "dup", "each", "each_entry_with_index", "each_key", "each_value", "empty?", "entries", "entries_capacity", "entries_full?", "entries_size", "entry_matches?", "fetch", "find_entry", "find_entry_with_index", "find_entry_with_index_linear_scan", "first_entry?", "first_key", "first_key?", "first_value", "first_value?", "fit_in_indices", "get_entry", "get_index", "has_key?", "has_value?", "hash", "indices_malloc_size", "indices_size", "initialize", "initialize_clone", "initialize_clone_entries", "initialize_compare_by_identity", "initialize_copy_non_entries_vars", "initialize_default_block", "initialize_dup", "initialize_dup_entries", "inspect", "invert", "key_for", "key_for?", "key_hash", "keys", "last_entry?", "last_key", "last_key?", "last_value", "last_value?", "malloc_entries", "malloc_indices", "merge", "merge!", "merge_into!", "next_index", "pretty_print", "proper_subset_of?", "proper_superset_of?", "put", "realloc_entries", "realloc_indices", "rehash", "reject", "reject!", "resize", "select", "select!", "set_entry", "set_index", "shift", "shift?", "size", "subset_of?", "superset_of?", "to_a", "to_a_impl", "to_h", "to_s", "transform_keys", "transform_values", "transform_values!", "update", "update_linear_scan", "upsert", "values", "values_at"]
IO.methods # => ["<<", "check_open", "close", "closed?", "decoder", "each_byte", "each_char", "each_line", "encoder", "encoding", "flush", "getb_to_end", "gets", "gets_peek", "gets_slow", "gets_to_end", "has_non_utf8_encoding?", "peek", "peek_or_read_utf8", "peek_or_read_utf8_masked", "pos", "pos=", "print", "printf", "puts", "read", "read_at", "read_byte", "read_bytes", "read_char", "read_char_with_bytesize", "read_fully", "read_fully?", "read_line", "read_string", "read_utf8", "read_utf8_byte", "rewind", "seek", "set_encoding", "skip", "skip_to_end", "tell", "tty?", "utf8_encoding?", "write", "write_byte", "write_bytes", "write_string", "write_utf8"]
File.methods # => ["delete", "initialize", "inspect", "path", "read_at", "size", "truncate"]
Mutex.methods # => ["initialize", "lock", "lock_slow", "synchronize", "try_lock", "unlock"]
PrettyPrint.methods # => ["break_outmost_groups", "breakable", "comma", "current_group", "fill_breakable", "flush", "group", "group_queue", "group_sub", "indent", "initialize", "list", "nest", "newline", "surround", "text"]
Process.methods # => ["channel", "close", "close_io", "copy_io", "ensure_channel", "error", "error?", "exists?", "finalize", "initialize", "input", "input?", "output", "output?", "pid", "signal", "stdio_to_fd", "terminate", "terminated?", "wait"]
Regex.methods # => ["+", "==", "===", "=~", "capture_count", "clone", "dup", "finalize", "hash", "initialize", "inspect", "internal_matches?", "match", "match_at_byte_index", "matches?", "matches_at_byte_index?", "name_table", "options", "source", "to_s"]
String.methods # => ["%", "*", "+", "<=>", "==", "=~", "[]", "[]?", "ascii_only?", "blank?", "byte_at", "byte_at?", "byte_delete_at", "byte_index", "byte_index_to_char_index", "byte_slice", "byte_slice?", "bytes", "bytesize", "calc_excess_left", "calc_excess_right", "camelcase", "capitalize", "center", "char_at", "char_bytesize_at", "char_index_to_byte_index", "chars", "check_no_null_byte", "chomp", "clone", "codepoint_at", "codepoints", "compare", "count", "delete", "delete_at", "downcase", "dump", "dump_char", "dump_hex", "dump_or_inspect", "dump_or_inspect_char", "dump_or_inspect_unquoted", "dump_unquoted", "dup", "each_byte", "each_byte_index_and_char_index", "each_char", "each_char_with_index", "each_codepoint", "each_grapheme", "each_grapheme_boundary", "each_line", "empty?", "encode", "ends_with?", "find_start_and_end", "grapheme_size", "graphemes", "gsub", "gsub_append", "gsub_ascii_char", "has_back_references?", "hash", "hexbytes", "hexbytes?", "includes?", "index", "insert", "insert_impl", "inspect", "inspect_char", "inspect_unquoted", "just", "lchop", "lchop?", "lines", "ljust", "lstrip", "match", "matches?", "partition", "presence", "pretty_print", "rchop", "rchop?", "remove_excess", "remove_excess_left", "remove_excess_right", "reverse", "rindex", "rjust", "rpartition", "rstrip", "scan", "scan_backreferences", "scrub", "single_byte_optimizable?", "size", "size_known?", "split", "split_by_empty_separator", "split_single_byte", "squeeze", "starts_with?", "strip", "sub", "sub_append", "sub_index", "sub_range", "succ", "titleize", "to_f", "to_f32", "to_f32?", "to_f64", "to_f64?", "to_f?", "to_f_impl", "to_i", "to_i128", "to_i128?", "to_i16", "to_i16?", "to_i32", "to_i32?", "to_i64", "to_i64?", "to_i8", "to_i8?", "to_i?", "to_s", "to_slice", "to_u128", "to_u128?", "to_u16", "to_u16?", "to_u32", "to_u32?", "to_u64", "to_u64?", "to_u8", "to_u8?", "to_unsafe", "to_unsigned_info", "to_utf16", "tr", "underscore", "unicode_delete_at", "unsafe_byte_at", "unsafe_byte_slice", "unsafe_byte_slice_string", "upcase", "valid_encoding?"]
Thread.methods # => ["detach", "event_base", "gc_thread_handler", "gc_thread_handler=", "initialize", "join", "main_fiber", "next", "next=", "previous", "previous=", "scheduler", "stack_address", "start", "to_unsafe"]
Bool.methods # => ["!=", "&", "==", "^", "clone", "hash", "to_s", "to_unsafe", "|"]
Int32.methods # => ["!=", "&", "&*", "&+", "&-", "*", "+", "-", "/", "<", "<=", "==", ">", ">=", "^", "clone", "leading_zeros_count", "popcount", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trailing_zeros_count", "unsafe_chr", "unsafe_div", "unsafe_mod", "unsafe_shl", "unsafe_shr", "|"]
Float64.methods # => ["!=", "*", "**", "+", "-", "/", "<", "<=", "==", ">", ">=", "ceil", "clone", "fdiv", "floor", "next_float", "prev_float", "round_away", "round_even", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_s", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trunc"]
Proc.methods # => ["==", "===", "arity", "call", "clone", "closure?", "closure_data", "hash", "internal_representation", "partial", "pointer", "to_s"]</syntaxhighlight>
== 脚註 ==
<references />
== 外部リンク ==
* [https://crystal-lang.org/ The Crystal Programming Language] {{---}} 公式サイト
** [https://crystal-lang.org/api/1.5.0/ Crystal 1.5.0 リファレンス]
** [https://play.crystal-lang.org/#/cr Compile & run code in Crystal] {{---}} playground
[[Category:Crystal|*]]
[[Category:プログラミング言語]]
{{NDC|007.64}}
ody21t5btmznltq7qwpog8fbb00rslj
205810
205809
2022-07-25T03:28:29Z
Ef3
694
/* 外部リンク */ * [https://crystal-lang.org/ The Crystal Programming Language] {{---}} 公式サイト ** [https://crystal-lang.org/reference/1.5/ ドキュメント] *** [https://crystal-lang.org/api/1.5.0/ APIマニュアル] ** [https://play.crystal-lang.org/#/cr Compile & run code in Crystal] {{---}} playground
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Crystal (プログラミング言語)}}
本書は、[[w:Crystal (プログラミング言語)|Crystal]]のチュートリアルです。
'''Crystal'''は、Ary Borenszweig、Juan Wajnerman、Brian Cardiffと300人以上の貢献者によって設計・開発された[汎用オブジェクト指向プログラミング言語です<ref>{{Cite web
|url=https://github.com/crystal-lang/crystal/graphs/contributors
|title=Contributors
|accessdate=2022-07-18
|website=github.com
}}</ref>。[[Ruby]] にヒントを得た構文を持ち、静的型チェックを備えた [[コンパイル型言語]]ですが、変数やメソッドの引数の型は一般には不要です。型は高度なグローバル[[型推論]]アルゴリズムによって解決される。<ref>{{Cite web
|url=http://crystal-lang.org/2013/09/23/type-inference-part-1.html
|title=Type inference part 1
|last=Brian J.
|first=Cardiff
|date=2013-09-09
|accessdate=2022-07-18
|website=crystal-lang.org
}}</ref>Crystalは[[Apache License]]バージョン2.0のもと、FOSSとしてリリースされています。
__TOC__
== Hello, World! ==
他の多くのチュートリアルがそうであるように、
私たちもまずはCrystalの世界にあいさつすることから始めましょう。
Rubyとの比較も兼ねて、[[Ruby#Hello, World!]]をそのまま実行してみます。
''hello.cr''というファイルを作り、次のように書いて保存して下さい<ref>Crystalのソースファイルの拡張子は''.cr'' です</ref>。
;hello.cr:<syntaxhighlight lang=Crystal>
puts 'Hello, World!'
</syntaxhighlight>
;コマンドラインでの操作:<syntaxhighlight lang="console">
% cat hello.cr
puts 'Hello, World!'
% crystal hello.cr
In hello.cr:1:6
1 | puts 'Hello, World!'
^
Error: unterminated char literal, use double quotes for strings
% sed -i -e "s@'@Q@g" -e 's@Q@"@g' hello.cr
% cat hello.cr
puts "Hello, World!"
% crystal hello.cr
Hello, World!
</syntaxhighlight>
この1行のスクリプトは、メソッド<code>puts</code> に文字リテラル<code>"Hello, World!"</code>を渡し呼出しています。
このプログラムは、[[Ruby#Hello, World!]]と同じですが、Crystalでは文字列リテラルは <code>"…"</code> で囲うのでそれだけ変更しました。
== プログラミング環境 ==
Crystalのプログラムを作り、コンパイル・実装するには、「オンライン実行環境を使う」・「エディト・コンパイル・実行環境を用意してそれを使う」の2通りの方法があります。
=== オンライン実行環境 ===
公式のオンライン実行環境、 https://play.crystal-lang.org/ があります。
まずは、これを使って本書に例示されているコードを実行してみることをお勧めします。
=== エディト・コンパイル・実行環境 ===
エディタについては本書では触れませんが、プログラミング時間の大半はエディタの操作に費やされるため、良いエディタを選択することが重要です。
Crystal の言語処理系は、 https://crystal-lang.org/install/ から入手します。
自分の、OSやGNU/Linuxであればディストリビューションに合わせてインストールしてください。
また、FreeBSDのように crystal と shards が別パッケージとなっていることもあるので、その場合は shards も追加インストールします。
多くの場合、インストールされた、 crystal はスタティック リンクされているので、ダイナミック リンク版の crystal を入手するには、スタティック リンク版の実行ファイルとソースコードを入手し、スタティック リンク版でソースから crystal をコンパイル・インストールする必要があります。
=== crystal コマンド ===
crystal コマンドは Crystal のコンパイラであると同時に、ビルドツールなどを含んだツールチェインです(プログラミング言語のCrystalは、先頭を大文字、コマンドのcrystalは、先頭を小文字にして区別します)。
[TODO: コマンドラインツール crystal の解説。 crystal ファイル名 は crystal run ファイル名 の短縮形で、インタープリタ的な実行…ではなく、内部ビルドツールでコンパイル・実行を行う]
== Ruby との違い ==
Crystalは、Rubyに触発された構文を持つものの、Rubyとの互換性をゴールに定めては'''いません'''。
このため、細部を見ると仕様に差異があり、Rubyのソースコードをcrystalに掛けても前節の 'Hello World' の様にコンパイルに失敗することがあります。
また、コンパイルできても実行結果に違いが出ることがあります。
ここでは、Ruby との違いについて実際のコードと双方の結果を比較することで、差異についての理解を深めていきます。
=== 整数型の特性 ===
;大きな整数:<syntaxhighlight lang=Crystal>
p 2 ** 999
p (2 ** 999).class
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
Integer
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
Unhandled exception: Arithmetic overflow (OverflowError)
from /usr/local/share/crystal/share/crystal/src/int.cr:295:9 in '**'
from pow.cr:1:1 in '__crystal_main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:101:7 in 'main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:127:3 in 'main'
from /usr/local/lib64/libc.so.6 in '__libc_start_main'
from /usr/local/.cache/crystal/crystal-run-pow.tmp in '_start'
from ???
</syntaxhighlight>
: Ruby の整数は、桁あふれが起こると自動的に多倍長整数に型変換されるので、継ぎ目なしに大きな数を扱うアルゴルズムが使えます。
: Crystal の整数は、固定長です(大きさについては[[#リテラルと型|後述]])。なので大きな答えになる式を評価すると桁あふれが生じます。桁あふれが生じますが、C言語のように寡黙に処理を続けるのではなく、実行時に例外(OverflowError)が上がるので、例外を捕捉し然るべき処置を施すことが可能です。
==== BigInt ====
<code>big</code> を <code>require</code> すると <code>BigInt</code> が使えるようになります。
;BigInt:<syntaxhighlight lang=Crystal>
require "big"
p BigInt.new(2) ** 999
p (BigInt.new(2) ** 999).class
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
BigInt
</syntaxhighlight>
: BigIntはプリミティブではなので、リテラル表現はありません。また、
::<syntaxhighlight lang=Crystal>
n : BigInt = 2
</syntaxhighlight>
::<syntaxhighlight lang=console>
Error: type must be BigInt, not Int32
</syntaxhighlight>
:: のように型アノテーションすることも出来ません。
=== リテラルと型 ===
;様々なリテラルと型:<syntaxhighlight lang=Crystal>
[nil, false, true, 42, 2.73, 'Q', "string", [1,2,3], {a:1, b:2}].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
[nil, NilClass]
[false, FalseClass]
[true, TrueClass]
[42, Integer]
[2.73, Float]
["Q", String]
["string", String]
[[1, 2, 3], Array]
[{:a=>1, :b=>2}, Hash]
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
[nil, Nil]
[false, Bool]
[true, Bool]
[42, Int32]
[2.73, Float64]
['Q', Char]
["string", String]
[[1, 2, 3], Array(Int32)]
[{a: 1, b: 2}, NamedTuple(a: Int32, b: Int32)]
</syntaxhighlight>
: Crystal の整数は Int32、浮動小数点数は Float64 です。
;サイズを指定した数リテラル:<syntaxhighlight lang=Crystal>
[1_i64, 2_u32, 3_u64, 4_i32, 5_i16, 6_u8, 7_i128, 8_u128, 3.14_f32, 1.44_f64].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;ruby:Rubyでは、サーフィックスの付いた数値リテラルは無効
;crystalの実行結果:<syntaxhighlight lang="console">
[1, Int64]
[2, UInt32]
[3, UInt64]
[4, Int32]
[5, Int16]
[6, UInt8]
[7, Int128]
[8, UInt128]
[3.14, Float32]
[1.44, Float64]
</syntaxhighlight>
: Crystal では、数値リテラルに _ で始まるサーフィックスを付け { i:符号付き整数, u:符号なし整数, f:浮動小数点数 } と { 8,16,32,64,128 } のビット幅の組合せです<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/literals/ Literals]</ref>。
=== for式がない ===
Crystal には、Ruby にはある for式がありません。
;Rubyのfor式の構文:<syntaxhighlight lang="ruby">
for 変数 in コレクション
文
end
</syntaxhighlight>
:コレクションは Range, Array, Hash など内部構造を持つオブジェクトです。
:for式は、最後に評価した値を返すので、for'''式'''です。
;for式のeachメソッドによる置換え:<syntaxhighlight lang="ruby">
for x in [ 2, 3, 5, 7, 11 ] do
p x
end
# ↓
[ 2, 3, 5, 7, 11 ].each do | x |
p x
end
</syntaxhighlight>
: の様にコレクションの each メソッドで置換え可能なので、Rubyからの移植でも小規模な書換えで済みます<ref>[https://github.com/crystal-lang/crystal/issues/830 "For" Loop support #830]</ref>(後述のマクロで実装できないかと思いましたが、いまのところ無理のようです)。
また loop 式もありませんが while true; … end で間に合います。Ruby では while 式の条件の次に do が置けますが、Crystal では置けません。
=== eval()がない ===
Crystal には eval() はありません。
Crystalはコンパイル型言語ですので、無理もないことです。
もし、Crystal で eval() を実装しようとすると、Common Lisp の様にインタープリターを丸ごとランタイムに含む必要があります。
これはリーズナブルな選択ではありません。
Crystal では、eval() が必要なケースに(限定的ですが)マクロを使うことで実現出来る可能性があります。
=== マクロ ===
Crystalには、Rubyにはないマクロがあります<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/macros/ Macros - Crystal]</ref>。Rubyは実行時にすべてのオブジェクトにアクセス出来て、メソッド生やし放題なのでマクロは必要ありませんが、Crystalはコンパイル時に型やメソッドを確定する必要があり、特にメソッドジェネレターとしてのマクロにニーズがあります。また、テンプレート言語的なマクロなので、環境変数による条件分岐や、コンテナを渡し繰返し処理する構文もあります(面白いことにマクロには for 文があり、反対にマクロの中では、eachメソッドは使えません)。マクロには <code><nowiki>{{</nowiki>attr.id}}</code> の様にASTへのアクセス手順が用意されており、半ば言語を拡張するようなアプローチを取ることも出来ます。
[TODO:ASTについての解説;コラム向き?]
;マクロを使ったattr_accessorのイミュレーション:<syntaxhighlight lang=crystal>
class Point
def initialize(@x : Int32, @y : Int32)
end
# macro定義
macro attr_accessor(*attrs)
{% for attr in attrs %}
def {{attr.id}}() @{{attr.id}} end
def {{attr.id}}=(var) @{{attr.id}} = var end
{% end %}
end
# macro呼出し
attr_accessor :x, :y
end
pt = Point.new(20, 30)
p [pt.x, pt.y]
t = pt.x
pt.x = pt.y
pt.y = t
p [pt.x, pt.y]
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
[20, 30]
[30, 20]
</syntaxhighlight>
: Ruby には、attr_accessor と言う「クラスのメンバーのアクセサーを自動生成するメソッド」がありますが、Crystalにはないようなので、マクロで実装しました。
:: attr_accessor :name からは
::<syntaxhighlight lang=ruby>
def name() @name end
def name=(val) @name = val end
</syntaxhighlight>相当のコードが生成されます。
[TODO:マクロの機能と構文の説明 *の付いた引数、 <nowiki>{{</nowiki>引数}}、{% … %} 構文]
==== マクロ p! ====
メソッド p は、与えられた「式」の inspaect() の返す値を puts しますが、マクロ p! は、それに先んじて(評価前の)「式」を表示します<ref>[https://crystal-lang.org/api/1.5.0/Crystal/Macros.html#p%21%28%2Aexpressions%29%3ANop-instance-method def p!(*expressions) : Nop]</ref>。
;p!の例:<syntaxhighlight lang=crystal>
x, y = true, false
p! x,y,x && y, x || y, x ^ y, !x, x != y, x == y
ary = [ 1, 2, 3 ]
p! ary
p! ary.map(&. << 1)
p! ary.map(&.to_f)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
x # => true
y # => false
x && y # => false
x || y # => true
x ^ y # => true
!x # => false
x != y # => true
x == y # => false
ary # => [1, 2, 3]
ary.map(&.<<(1)) # => [2, 4, 6]
ary.map(&.to_f) # => [1.0, 2.0, 3.0]
</syntaxhighlight>
===== 入れ子のp! =====
マクロ p! は入れ子に出来ます。また、一旦ASTに変換してから再度ソースコードに変換するので、等価な別の構文に変換されることがあります。
;入れ子のp!:<syntaxhighlight lang=crystal>
p! (
100.times{|i|
p! i
break i if i > 12
}
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(100.times do |i|
p!(i)
if i > 12
break i
end
end) # => i
# => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
i # => 6
i # => 7
i # => 8
i # => 9
i # => 10
i # => 11
i # => 12
i # => 13
13
</syntaxhighlight>
=== クラス ===
==== シンプルなクラス ====
;シンプルなクラス:<syntaxhighlight lang=crystal highlight="2" line>
class Hello
def initialize(@name : String = "World")
end
def greeting
puts "Hello #{@name}!"
end
end
hello = Hello.new()
hello.greeting
universe = Hello.new("Universe")
universe.greeting
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Hello World!
Hello Universe!
</syntaxhighlight>
:;初期化メソッド
:: <syntaxhighlight lang=crystal line start=4>
def initialize(@name : String = "World")
end
</syntaxhighlight>
::Rubyであれば
:: <syntaxhighlight lang=ruby line start=4>
def initialize(name = "World")
@name = name
end
</syntaxhighlight>
::とするところですが、Crystalでは、型アノテーション <code> : String</code> を使い、引数の型を限定しました。
::また、(@ 付きの)アトリビュート名を仮引数にすると、そのままアトリビュート(a.k.a. インスタンス変数)に仮引数が代入されます。
::これは、C++のコンストラクターのメンバー初期化リストと同じアイディアですが、Crystalではインスタンス変数に @ が前置されるので、仮引数に @ が出現すればインスタンス変数の初期値だと自明で、聡明な選択です。
==== 都市間の大圏距離 ====
[[Ruby#ユーザー定義クラス]]の都市間の大圏距離を求めるメソッドを追加した例を、Crystalに移植しました。
;都市間の大圏距離:<syntaxhighlight lang=crystal highlight=”2,7,12” line>
class GeoCoord
getter :longitude, :latitude
def initialize(@longitude : Float64, @latitude : Float64)
end
def to_s(io)
ew, ns = "東経", "北緯"
long, lat = @longitude, @latitude
ew, long = "西経", -long if long < 0.0
ns, lat = "南緯", -lat if lat < 0.0
io << "(#{ew}: #{long}, #{ns}: #{lat})"
end # https://github.com/crystal-lang/crystal/issues/259
def distance(other)
i, r = Math::PI / 180, 6371.008
Math.acos(Math.sin(@latitude*i) * Math.sin(other.latitude * i) +
Math.cos(@latitude*i) * Math.cos(other.latitude * i) * Math.cos(@longitude * i - other.longitude * i)) * r
end
end
# メソッドの先頭を大文字に出来ないのでクラス名のメソッドは作ることが出来ない
# def GeoCoord(lng : Float64, lat : Float64)
# GeoCoord.new(lng, lat)
# end
Sites = {
"東京駅": GeoCoord.new(139.7673068, 35.6809591),
"シドニー・オペラハウス": GeoCoord.new(151.215278, -33.856778),
"グリニッジ天文台": GeoCoord.new(-0.0014, 51.4778),
}
Sites.each { |name, gc|
puts "#{name}: #{gc}"
}
puts ""
keys, len = Sites.keys, Sites.size
keys.each_with_index { |x, i|
y = keys[(i + 1) % len]
puts "#{x} ⇔ #{y}: #{Sites[x].distance(Sites[y])} [km]"
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
東京駅: (東経: 139.7673068, 北緯: 35.6809591)
シドニー・オペラハウス: (東経: 151.215278, 南緯: 33.856778)
グリニッジ天文台: (西経: 0.0014, 北緯: 51.4778)
東京駅 ⇔ シドニー・オペラハウス: 7823.269299386704 [km]
シドニー・オペラハウス ⇔ グリニッジ天文台: 16987.2708377249 [km]
グリニッジ天文台 ⇔ 東京駅: 9560.546566490015 [km]
</syntaxhighlight>
:Crystal には、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> はありませんが、標準ライブラリーのマクロに <syntaxhighlight lang=crystal inline> getter </syntaxhighlight>があるので
:: <syntaxhighlight lang=crystal line start=2>
getter :longitude, :latitude
</syntaxhighlight>
::としました。
::将来、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> が実装される可能性はありますが、姉妹品の<syntaxhighlight lang=crystal inline> setter </syntaxhighlight> との併用が下位互換性を考えると確実です。
: to_s は、Ruby ならば
:: <syntaxhighlight lang=ruby line start=7>
def to_s()
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
"(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
:: ですが、Crystalでは追加の引数 <var>io</var> が必要で
:: <syntaxhighlight lang=ruby line start=7>
def to_s(io)
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
io << "(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
: Ruby にはクラス名と同じ名前のメソッドで .new を呼出す文化があるのですが、Crystalはメソッドの先頭を大文字に出来ないので、これは見送りました。
==== 包含と継承 ====
[[JavaScript/クラス#包含と継承]]を、Rubyに移植した[[Ruby#包含と継承]]を、Crystalに移植しました。
;包含と継承の例:<syntaxhighlight lang=crystal line>
class Point
def initialize(@x = 0, @y = 0)
end
def inspect(io)
io << "x:#{@x}, y:#{@y}"
end
def move(dx = 0, dy = 0)
@x, @y = @x + dx, @y + dy
self
end
end
class Shape
def initialize(x = 0, y = 0)
@location = Point.new(x, y)
end
def inspect(io)
@location.inspect(io)
end
def move(x, y)
@location.move(x, y)
self
end
end
class Rectangle < Shape
def initialize(x = 0, y = 0, @width = 0, @height = 0)
super(x, y)
end
def inspect(io)
super(io)
io << ", width:#{@width}, height:#{@height}"
end
end
rct = Rectangle.new(12, 32, 100, 50)
p! rct,
rct.is_a?(Rectangle),
rct.is_a?(Shape),
rct.is_a?(Point),
rct.move(11, 21)
(END)</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
rct # => x:12, y:32, width:100, height:50
rct.is_a?(Rectangle) # => true
rct.is_a?(Shape) # => true
rct.is_a?(Point) # => false
rct.move(11, 21) # => x:23, y:53, width:100, height:50
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy inclusion-and-inheritance.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (16 bytes)
. @location : Point (8 bytes)
|
+- class Rectangle (24 bytes)
@width : Int32 (4 bytes)
@height : Int32 (4 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
===== superclass と subclasses =====
Crystal には、RubyのClassにあるメソッド superclass と subclasses がないので、マクロで実装しました。
;superclass と subclasses:<syntaxhighlight lang=crystal line>
class Class
def self.superclass
{{ @type.superclass }}
end
def self.subclasses : Array(self.class)
{{ @type.subclasses }}.map(&.as(self.class))
end
def self.all_subclasses : Array(self.class)
{% begin %}
[{{ @type.all_subclasses.join(",").id }}] of self.class
{% end %}
end
end
class A end
class AA < A end
class AAA < AA end
class AAB < AA end
class AB < A end
p! A,
A.subclasses,
A.all_subclasses,
AAA.superclass,
A.superclass
c = AAA
while !c.is_a? Nil
p! c.superclass
c = c.superclass
end</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
A # => A
A.subclasses # => [AA, AB]
A.all_subclasses # => [AA, AAA, AAB, AB]
AAA.superclass # => AA
A.superclass # => Reference
c.superclass # => AA
c.superclass # => A
c.superclass # => Reference
c.superclass # => Object
c.superclass # => nil
</syntaxhighlight>
==== 抽象クラス ====
[[Java/抽象クラス]]を、Crystalに移植しました。
;抽象クラスの宣言:<syntaxhighlight lang=Java>
abstract class クラス名
#
end
</syntaxhighlight>
: このクラス名は、 .new でインスタンス化出来ません。
:: Error: can't instantiate abstract class クラス名
: となります。
:インスタンス化することは出来ませんが、抽象クラスを別のクラスが継承する事は出来ます。
:また、抽象クラスを <code>super()</code> を使うことでメソッドを呼び出せるので、抽象メソッドではないメソッド(具象メソッド)を持つことも、インスタンス変数も持つことも出来ます。
:'''抽象クラスの例'''では、Shapeのinitializeメソッドが抽象クラスの具象メソッドとなっています。
;抽象メソッドの宣言:<syntaxhighlight lang=Java>
abstract def メソッド名
</syntaxhighlight>
: 派生先のクラスで、「メソッド名」を定義(def)し忘れると
:: Error: abstract `def クラス名#メソッド名()` must be implemented by クラス名
: となります
;抽象クラスの例:<syntaxhighlight lang=crystal line>
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
class Recrangle < Shape
def initialize(x, y, @w = 0.0, @h = 0.0)
super(x, y)
end
def to_s(io)
io << "Rectanle(#{@x}, #{@y}, #{@w}, #{@h})"
end
def area
@w * @h
end
end
class Circle < Shape
def initialize(x, y, @r = 0.0)
super(x, y)
end
def to_s(io)
io << "Circle(#{@x}, #{@y}, #{@r})"
end
def area
3.1425926536 * @r * @r
end
end
shapes = [
Square.new(5.0, 10.0, 15.0),
Recrangle.new(13.0, 23.0, 20.0, 10.0),
Circle.new(3.0, 2.0, 20.0),
] of Shape
shapes.each do |shape|
puts("#{shape}: #{shape.area}")
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Square(5.0, 10.0, 15.0): 225.0
Rectanle(13.0, 23.0, 20.0, 10.0): 200.0
Circle(3.0, 2.0, 20.0): 1257.03706144
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy abstract.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (24 bytes)
. @x : Float64 (8 bytes)
. @y : Float64 (8 bytes)
|
+- class Circle (32 bytes)
| @r : Float64 (8 bytes)
|
+- class Recrangle (40 bytes)
| @w : Float64 (8 bytes)
| @h : Float64 (8 bytes)
|
+- class Square (32 bytes)
@wh : Float64 (8 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
: 「包含と継承の例」と比べると、ShapeとRectangleが同じ階層にあることがわかると思います。
[TODO:virtual class::いい例がない]
== キーワード ==
Crystalのキーワード( ''keywords'' ) は、以下の通り。
<code>abstract</code> <code>alias</code> <code>as</code> <code>asm</code> <code>begin</code> <code>break</code> <code>case</code> <code>class</code> <code>def</code> <code>do</code> <code>else</code> <code>elsif</code> <code>end</code> <code>ensure</code> <code>enum</code> <code>extend</code> <code>for</code> <code>fun</code> <code>if</code> <code>include</code> <code>instance_sizeof</code> <code>lib</code> <code>macro</code> <code>module</code> <code>next</code> <code>of</code> <code>out</code> <code>pointerof</code> <code>private</code> <code>protected</code> <code>rescue</code> <code>return</code> <code>require</code> <code>select</code> <code>sizeof</code> <code>struct</code> <code>super</code> <code>then</code> <code>type</code> <code>typeof</code> <code>uninitialized</code> <code>union</code> <code>unless</code> <code>until</code> <code>when</code> <code>while</code> <code>with</code> <code>yield</code>
<!--
<code>__DIR__</code> <code>__END_LINE__</code> <code>__FILE__</code> <code>__LINE__</code>
-->
== 演算子 ==
Crystalは、1つ、2つ、または3つのオペランドを持つ数多くの演算子をサポートしています<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/operators.html Operators]access-date:2022-07-22</ref>。
演算子式は、実際にはメソッド呼び出しとしてパースされます。例えば、<code>a + b</code> は <code>a.+(b)</code> と意味的に同じで、引数 b を持つ a のメソッド + を呼び出すことになります。
{| class="wikitable"
|+ 演算子の優先度
!種類
!演算子
|-
|インデックス アクセサー
|<code>[]</code>, <code>[]?</code>
|-
|単項
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>, <code>!</code>, <code>~</code>
|-
|指数
|<code>**</code>, <code>&**</code>
|-
|乗除
|<code>*</code>, <code>&*</code>, <code>/</code>, <code>//</code>, <code>%</code>
|-
|加減
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>
|-
|シフト
|<code><<</code>, <code>>></code>
|-
|ビット間 AND
|<code>&</code>
|-
|ビット間 OR/XOR
|<code><nowiki>|</nowiki></code>,<code>^</code>
|-
|等値
|<code>==</code>, <code>!=</code>, <code>=~</code>, <code>!~</code>, <code>===</code>
|-
|比較
|<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>, <code><=></code>
|-
|論理 AND
|<code>&&</code>
|-
|論理 OR
|<code><nowiki>||</nowiki></code>
|-
|Range
|<code>..</code>, <code>...</code>
|-
|条件
|<code>?:</code>
|-
|代入
|<code>=</code>, <code>[]=</code>, <code>+=</code>, <code>&+=</code>, <code>-=</code>, <code>&-=</code>, <code>*=</code>, <code>&*=</code>, <code>/=</code>, <code>//=</code>, <code>%=</code>, <code><nowiki>|=</nowiki></code>, <code>&=</code>,<code>^=</code>,<code>**=</code>,<code><<=</code>,<code>>>=</code>, <code><nowiki>||=</nowiki></code>, <code>&&=</code>
|-
|スプラット
|<code>*</code>, <code>**</code>
|}
== 制御構造 ==
'''[[w:制御構造|制御構造]]'''(せいぎょこうぞう、''control flow'')とは、「順次」「分岐」「反復」という基本的な処理のことを言います。
{{コラム|Crystalの真理値|2=
制御構造は「条件式」が真であるか偽であるかによって分岐や反復の振る舞いが変わります。
では「条件式」が真・偽はどの様に決まるのでしょう?
Crystalでは <code>false</code> あるいは <code>nil</code> であると偽、それ以外が真です。
なので <code>0</code> も <code>[]</code>(空のArray) も <code>{}</code>(空のNamedTuple)も真です。
}}
=== 条件分岐 ===
Crystalの条件分岐には、[[#if|if]], [[#until|until]] と [[#case|case]]の3つの構文があります。
==== if ====
'''[[w:if|if]]'''は条件式によって実行・否を切り替える構造構文で、評価した式の値を返すので条件演算子でもあります。
;ifの例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
if a < 0
puts "minus"
elsif a > 0
puts "plus"
elsif a == 0
puts "zero"
else
puts a
end
p! (
if a < 0
"minus"
elsif a > 0
"plus"
elsif a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(if a < 0
"minus"
else
if a > 0
"plus"
else
if a == 0
"zero"
else
a
end
end
end) # => NaN
</syntaxhighlight>
:; elsif節:ifは、オプショナルな elsif 節を設け、条件式が偽であった時に別の条件に合致した処理を実行させることが出来ます。
:; else節:ifは、オプショナルな else 節を設け、条件式が偽であった時に処理を実行させることが出来ます。
: ifは値を返すので、メソッドの実引数に使うことが出来ますし、代入演算の右辺にも使えます。
==== 後置のif ====
Crystalには、RubyやPerlのような後置のifがあります。
;後置のifの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" if n == 0
puts "nは1" if n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは0
</syntaxhighlight>
==== unless====
'''unless'''(アンレス)は条件式によって実行・否を切り替える構造構文ですが、ifとは条件式に対する挙動が逆です。
;unless文の例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
unless a == 0
puts "Non-zero"
else
puts a
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Non-zero
</syntaxhighlight>
:; else節 : unless文は、オプショナルな else 節を設け、条件式が真であった時に処理を実行させることが出来ます。
::また、unless文は elsif 節は持てません。
==== 後置のunless ====
Crystalには、RubyやPerlのような後置のunlessがあります。
;後置のunlessの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" unless n == 0
puts "nは1" unless n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは1ではない
</syntaxhighlight>
==== case ====
caseは、複数の条件式によって処理を降る分ける用途の為に用意されています。
;caseの例:<syntaxhighlight lang=crystal line>
n = 2
case n
when 1
puts "one"
when 2
puts "two"
when 3
puts "three"
else
puts "other"
end
p! (
case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
two
(case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end) # => "two"</syntaxhighlight>
:C言語系のswitch文に慣れた人はbreakがないことに気がつくと思います。Crystalのcaseはfall throughしませんし、fall throughさせる方法もありません。
===== when節が定数でなく式を受付けます =====
[[#if|if]]を使ったコードをcaseに書き換えてみましょう。
;case の式の省略:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
case
when a < 0
puts "minus"
when a > 0
puts "plus"
when a == 0
puts "zero"
else
puts a
end
p! (
case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end) # => NaN
</syntaxhighlight>
このコードは when 節の式の値とcaseの式を <code>===</code> で比較し、最初に一致した when に対応する式が実行される事を利用しています。
===== 型による分岐 =====
when 節が式ではなく型であった場合、caseの式を <code>is_a?</code> で評価し、最初に一致した when に対応する式が実行されます。
;型による分岐:<syntaxhighlight lang=crystal line>
p! 0.class,
0.is_a?(Object),
0.is_a?(Int32),
0.is_a?(Number),
0.is_a?(String)
case 0
when String
puts "String"
when Number
puts "Number"
when Int32
puts "Int32"
when Object
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0.class # => Int32
0.is_a?(Object) # => true
0.is_a?(Int32) # => true
0.is_a?(Number) # => true
0.is_a?(String) # => false
Number
</syntaxhighlight>
暗黙のオブジェクト構文を使うと
:<syntaxhighlight lang=crystal line>
case 0
when .is_a?(String)
puts "String"
when .is_a?(Number)
puts "Number"
when .is_a(Int32)
puts "Int32"
when .is_a(Object)
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
:と書くことが出来ます。
:: メソッドは、.is_a? に限定しないので、 .odd? .even? .include? など Bool を返すメソッドなら何でも使えます。
when に対応する式は、1つのことが珍しくないので、その場合は省略可能な then を補うと、1行で書けます。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
[TODO:タプルとダミー識別子 _ ]
===== 網羅性の検査 =====
when の代わりに in を使用すると、exhaustive case 式が作成されます。exhaustive case では、必要な in 条件を省略するとコンパイル時にエラーとなります。排他的論理和では、when 節と else 節を含むことはできません。
コンパイラは、以下の in 条件をサポートしています。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
caseの式がユニオンの場合、各要素型を条件として使用することができる。
;組合型チェック:<syntaxhighlight lang=crystal line>
var : ( Bool | Int32 | Float64 )?
var = 3.14
p! (
case var
in Bool then var ? 1 : 0
in Int32 then var
in Float64 then var.to_i
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
(case var
in Bool
var ? 1 : 0
in Int32
var
in Float64
var.to_i
end) # => 3
</syntaxhighlight>
[TODO:case in は enum にも使える]
[TODO:短絡評価 && || ]
=== 繰返し ===
Crystalには、他のプログラミング言語のような[[#繰返し構文|繰返し構文]]と、[[#イテレーターメソッド|イテレーターメソッド]]があります。
==== 繰返し構文 ====
Crystalの繰返し構文には、while と untilの2つがあります<ref>for も do-while も loop もありません。</ref>。
===== while =====
while(ホワイル)は条件が'''真'''である間、式を実行しつづけます。
;構文:<syntaxhighlight lang=crystal>
while 条件式
式1
式2
:
式n
end
</syntaxhighlight>
: Rubyと違い、条件式の後ろに <code>do</code> をつけることは出来ません。
;while文のコード例:<syntaxhighlight lang=crystal line>
i = 0
p! (
while i < 10
p! i
i += 1
break i if i > 5
end
)
</syntaxhighlight>
: 2行目の <code>i < 5</code>が真の間、次の2行を繰返します。
: 4行目の <code>i += 1</code> は <code>i = i + 1</code> の構文糖
;実行結果:<syntaxhighlight lang="text">
(while i < 10
p!(i)
i = i + 1
if i > 5
break i
end
end)# =>
i # => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
6
</syntaxhighlight>
===== until =====
until(アンティル)は条件が'''偽'''である間、式を実行しつづけます。whileとは条件に対する挙動が逆です。
;構文:<syntaxhighlight lang=crystal>
until 条件式 [ do ]
文1
文2
:
文n
end
</syntaxhighlight>
: <code>do</code> は省略できます。
;untilのコード例:<syntaxhighlight lang=crystal line>
i = 0
until i == 3
puts i
i += 1
end
</syntaxhighlight>
: 2行目の <code>i == 3</code>が偽の間、次の2行を繰返します。
;実行結果:<syntaxhighlight lang="text">
0
1
2
</syntaxhighlight>
===== for =====
Crystalにはforがありませんが、コレクションのイテレーションメソッドを使うことで繰返しを簡素に実現出来ます。
==== Rangeオブジェクト ====
Rangeオブジェクトは、整数の区間を表し範囲演算子 <code>開始 ... 終了</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
rng = 1..3
puts rng.class
rng.each do | n |
puts "#{n}番";
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Range(Int32, Int32)
1番
2番
3番
</syntaxhighlight>
==== Arrayオブジェクト ====
Arrayオブジェクトは、任意の Crystal オブジェクトを要素として持つことができます。
配列式<code>[要素1, 要素2, … 要素n]</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
animals = ["ネコ", "金魚", "ハムスター"]
puts animals.class
animals.each do | animal |
puts "動物 #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Array(String)
動物 ネコ
動物 金魚
動物 ハムスター
</syntaxhighlight>
==== NamedTupleオブジェクト ====
NamedTupleオブジェクトは、任意の Crystal オブジェクトをキーに、任意の Crystal オブジェクトを値に持つことができる連想配列です。
NamedTuple式<code>{キー1 => 値1, キー2 => 値2, キーn => 値n}</code> で生成します。
また、キーが Symbol の場合
NamedTuple式<code>{キー1: 値1, キー2: 値2, キーn: 値n}</code> で生成することが出来ます。
;コード:<syntaxhighlight lang=crystal>
animals = {cat: "ネコ", gold_fish: "金魚", hamster: "ハムスター"}
puts animals.class
animals.each do | en, animal |
puts "動物 #{en}: #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NamedTuple(cat: String, gold_fish: String, hamster: String)
動物 cat: ネコ
動物 gold_fish: 金魚
動物 hamster: ハムスター
</syntaxhighlight>
このように、Crystalではforがなくてもコレクションのメソッドで同様の処理を実現できます。
===== loop =====
loop、ありません。
while true で代用します。
;loopの代用コード例:<syntaxhighlight lang=crystal line>
i = 1
while true
puts "0b%b" % i
i <<= 1
break if i > 2**8
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0b1
0b10
0b100
0b1000
0b10000
0b100000
0b1000000
0b10000000
0b100000000
</syntaxhighlight>
:5行目の、<code>break if i > 2**8</code>でループを脱出するようにしています。この様に break や return あるいは例外が上がらないとループは永久に終わりません。
:このコードは、Crystalにはない do-while文を模倣する例にもなっています。
==== イテレーターメソッド ====
===== Integer#times =====
Integer#timesは与えられたブロックをオブジェクトの示す整数値回くりかえします。
:コード<syntaxhighlight lang=crystal>
3.times{ puts "Hello, world!" }
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello, world!
Hello, world!
Hello, world!
</syntaxhighlight>
;繰返したい処理が2行以上ある場合:<syntaxhighlight lang=crystal>
3.times {
puts "Hello"
puts "World"
puts ""
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello
World
Hello
World
Hello
World
</syntaxhighlight>
;ループ変数を使た例:<syntaxhighlight lang=crystal>
3.times do |i|
puts "#{i}の倍は#{2 * i}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0の倍は0
1の倍は2
2の倍は4
</syntaxhighlight>
;ブロックを伴わないtimesメソッド:<syntaxhighlight lang=crystal>
iter = 3.times
puts iter.class
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
# puts iter.next # `next': StopIteration: iteration reached an end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Int::TimesIterator(Int32)
iter.next # => 0
iter.next # => 1
iter.next # => 2
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
</syntaxhighlight>
: Integer#times にブロックを渡さないと、Int::TimesIterator([T])オブジェクトが返ります。
: Int::TimesIterator([T])オブジェクトは外部イテレーターと呼ばれnextメソッドで反復を行えます。
== メソッド ==
=== クラスのメソッド一覧 ===
Crystal には、Objectクラスにmethodsメソッドがないので、マクロで実装しました。
;RubyのObject#methods:<syntaxhighlight lang=ruby>
p Object.methods.sort,
Integer.methods.sort,
Float.methods.sort,
Array.methods.sort,
Range.methods.sort
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :sqrt, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :[], :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
</syntaxhighlight>
;Crystalに実装したmethodsマクロ:<syntaxhighlight lang=crystal>
class Object
macro methods
{{ @type.methods.map(&.name.stringify).sort.uniq }}
end
end
p! Object.methods,
Reference.methods,
Array.methods,
Box.methods,
Channel.methods,
Deque.methods,
Dir.methods,
Exception.methods,
ArgumentError.methods,
DivisionByZeroError.methods,
IndexError.methods,
InvalidByteSequenceError.methods,
Fiber.methods,
Hash.methods,
IO.methods,
File.methods,
Mutex.methods,
PrettyPrint.methods,
Process.methods,
Regex.methods,
String.methods,
Thread.methods,
Bool.methods,
Int32.methods,
Float64.methods,
Proc.methods
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
Object.methods # => ["!=", "!~", "==", "===", "=~", "class", "crystal_type_id", "dup", "hash", "in?", "inspect", "itself", "not_nil!", "pretty_inspect", "pretty_print", "tap", "to_s", "try", "unsafe_as"]
Reference.methods # => ["==", "dup", "exec_recursive", "exec_recursive_clone", "hash", "inspect", "object_id", "pretty_print", "same?", "to_s"]
Array.methods # => ["&", "*", "+", "-", "<<", "<=>", "==", "[]", "[]=", "[]?", "calculate_new_capacity", "check_needs_resize", "check_needs_resize_for_unshift", "clear", "clone", "compact", "compact!", "concat", "delete", "delete_at", "dup", "each_repeated_permutation", "fill", "first", "flatten", "increase_capacity", "increase_capacity_for_unshift", "index", "initialize", "insert", "inspect", "internal_delete", "last", "map", "map_with_index", "needs_resize?", "pop", "pop?", "pretty_print", "product", "push", "reject!", "remaining_capacity", "repeated_permutations", "replace", "reset_buffer_to_root_buffer", "resize_if_cant_insert", "resize_to_capacity", "resize_to_capacity_for_unshift", "reverse", "root_buffer", "rotate", "rotate!", "select!", "shift", "shift?", "shift_buffer_by", "shift_when_not_empty", "shuffle", "size", "size=", "skip", "sort", "sort!", "sort_by", "sort_by!", "to_a", "to_lookup_hash", "to_s", "to_unsafe", "to_unsafe_slice", "transpose", "truncate", "uniq", "uniq!", "unsafe_fetch", "unsafe_put", "unshift", "unstable_sort", "unstable_sort!", "unstable_sort_by", "unstable_sort_by!", "|"]
Box.methods # => ["initialize", "object"]
Channel.methods # => ["close", "closed?", "dequeue_receiver", "dequeue_sender", "initialize", "inspect", "pretty_print", "receive", "receive?", "receive_impl", "receive_internal", "receive_select_action", "receive_select_action?", "send", "send_internal", "send_select_action"]
Deque.methods # => ["+", "<<", "==", "buffer", "clear", "clone", "concat", "delete", "delete_at", "dup", "each", "halfs", "increase_capacity", "initialize", "insert", "inspect", "internal_delete", "pop", "pop?", "pretty_print", "push", "reject!", "rotate!", "select!", "shift", "shift?", "size", "size=", "to_s", "unsafe_fetch", "unsafe_put", "unshift"]
Dir.methods # => ["children", "close", "each", "each_child", "entries", "initialize", "inspect", "path", "pretty_print", "read", "rewind", "to_s"]
Exception.methods # => ["backtrace", "backtrace?", "callstack", "callstack=", "cause", "initialize", "inspect", "inspect_with_backtrace", "message", "to_s"]
ArgumentError.methods # => ["initialize"]
DivisionByZeroError.methods # => ["initialize"]
IndexError.methods # => ["initialize"]
InvalidByteSequenceError.methods # => ["initialize"]
Fiber.methods # => ["cancel_timeout", "dead?", "enqueue", "initialize", "inspect", "makecontext", "name", "name=", "next", "next=", "previous", "previous=", "push_gc_roots", "resumable?", "resume", "resume_event", "run", "running?", "stack_bottom", "stack_bottom=", "timeout", "timeout_event", "timeout_select_action", "timeout_select_action=", "to_s"]
Hash.methods # => ["==", "[]", "[]=", "[]?", "add_entry_and_increment_size", "clear", "clear_entries", "clear_impl", "clear_indices", "clone", "compact", "compact!", "compare_by_identity", "compare_by_identity?", "compute_indices_bytesize", "delete", "delete_entry", "delete_entry_and_update_counts", "delete_impl", "delete_linear_scan", "dig", "dig?", "do_compaction", "double_indices_size", "dup", "each", "each_entry_with_index", "each_key", "each_value", "empty?", "entries", "entries_capacity", "entries_full?", "entries_size", "entry_matches?", "fetch", "find_entry", "find_entry_with_index", "find_entry_with_index_linear_scan", "first_entry?", "first_key", "first_key?", "first_value", "first_value?", "fit_in_indices", "get_entry", "get_index", "has_key?", "has_value?", "hash", "indices_malloc_size", "indices_size", "initialize", "initialize_clone", "initialize_clone_entries", "initialize_compare_by_identity", "initialize_copy_non_entries_vars", "initialize_default_block", "initialize_dup", "initialize_dup_entries", "inspect", "invert", "key_for", "key_for?", "key_hash", "keys", "last_entry?", "last_key", "last_key?", "last_value", "last_value?", "malloc_entries", "malloc_indices", "merge", "merge!", "merge_into!", "next_index", "pretty_print", "proper_subset_of?", "proper_superset_of?", "put", "realloc_entries", "realloc_indices", "rehash", "reject", "reject!", "resize", "select", "select!", "set_entry", "set_index", "shift", "shift?", "size", "subset_of?", "superset_of?", "to_a", "to_a_impl", "to_h", "to_s", "transform_keys", "transform_values", "transform_values!", "update", "update_linear_scan", "upsert", "values", "values_at"]
IO.methods # => ["<<", "check_open", "close", "closed?", "decoder", "each_byte", "each_char", "each_line", "encoder", "encoding", "flush", "getb_to_end", "gets", "gets_peek", "gets_slow", "gets_to_end", "has_non_utf8_encoding?", "peek", "peek_or_read_utf8", "peek_or_read_utf8_masked", "pos", "pos=", "print", "printf", "puts", "read", "read_at", "read_byte", "read_bytes", "read_char", "read_char_with_bytesize", "read_fully", "read_fully?", "read_line", "read_string", "read_utf8", "read_utf8_byte", "rewind", "seek", "set_encoding", "skip", "skip_to_end", "tell", "tty?", "utf8_encoding?", "write", "write_byte", "write_bytes", "write_string", "write_utf8"]
File.methods # => ["delete", "initialize", "inspect", "path", "read_at", "size", "truncate"]
Mutex.methods # => ["initialize", "lock", "lock_slow", "synchronize", "try_lock", "unlock"]
PrettyPrint.methods # => ["break_outmost_groups", "breakable", "comma", "current_group", "fill_breakable", "flush", "group", "group_queue", "group_sub", "indent", "initialize", "list", "nest", "newline", "surround", "text"]
Process.methods # => ["channel", "close", "close_io", "copy_io", "ensure_channel", "error", "error?", "exists?", "finalize", "initialize", "input", "input?", "output", "output?", "pid", "signal", "stdio_to_fd", "terminate", "terminated?", "wait"]
Regex.methods # => ["+", "==", "===", "=~", "capture_count", "clone", "dup", "finalize", "hash", "initialize", "inspect", "internal_matches?", "match", "match_at_byte_index", "matches?", "matches_at_byte_index?", "name_table", "options", "source", "to_s"]
String.methods # => ["%", "*", "+", "<=>", "==", "=~", "[]", "[]?", "ascii_only?", "blank?", "byte_at", "byte_at?", "byte_delete_at", "byte_index", "byte_index_to_char_index", "byte_slice", "byte_slice?", "bytes", "bytesize", "calc_excess_left", "calc_excess_right", "camelcase", "capitalize", "center", "char_at", "char_bytesize_at", "char_index_to_byte_index", "chars", "check_no_null_byte", "chomp", "clone", "codepoint_at", "codepoints", "compare", "count", "delete", "delete_at", "downcase", "dump", "dump_char", "dump_hex", "dump_or_inspect", "dump_or_inspect_char", "dump_or_inspect_unquoted", "dump_unquoted", "dup", "each_byte", "each_byte_index_and_char_index", "each_char", "each_char_with_index", "each_codepoint", "each_grapheme", "each_grapheme_boundary", "each_line", "empty?", "encode", "ends_with?", "find_start_and_end", "grapheme_size", "graphemes", "gsub", "gsub_append", "gsub_ascii_char", "has_back_references?", "hash", "hexbytes", "hexbytes?", "includes?", "index", "insert", "insert_impl", "inspect", "inspect_char", "inspect_unquoted", "just", "lchop", "lchop?", "lines", "ljust", "lstrip", "match", "matches?", "partition", "presence", "pretty_print", "rchop", "rchop?", "remove_excess", "remove_excess_left", "remove_excess_right", "reverse", "rindex", "rjust", "rpartition", "rstrip", "scan", "scan_backreferences", "scrub", "single_byte_optimizable?", "size", "size_known?", "split", "split_by_empty_separator", "split_single_byte", "squeeze", "starts_with?", "strip", "sub", "sub_append", "sub_index", "sub_range", "succ", "titleize", "to_f", "to_f32", "to_f32?", "to_f64", "to_f64?", "to_f?", "to_f_impl", "to_i", "to_i128", "to_i128?", "to_i16", "to_i16?", "to_i32", "to_i32?", "to_i64", "to_i64?", "to_i8", "to_i8?", "to_i?", "to_s", "to_slice", "to_u128", "to_u128?", "to_u16", "to_u16?", "to_u32", "to_u32?", "to_u64", "to_u64?", "to_u8", "to_u8?", "to_unsafe", "to_unsigned_info", "to_utf16", "tr", "underscore", "unicode_delete_at", "unsafe_byte_at", "unsafe_byte_slice", "unsafe_byte_slice_string", "upcase", "valid_encoding?"]
Thread.methods # => ["detach", "event_base", "gc_thread_handler", "gc_thread_handler=", "initialize", "join", "main_fiber", "next", "next=", "previous", "previous=", "scheduler", "stack_address", "start", "to_unsafe"]
Bool.methods # => ["!=", "&", "==", "^", "clone", "hash", "to_s", "to_unsafe", "|"]
Int32.methods # => ["!=", "&", "&*", "&+", "&-", "*", "+", "-", "/", "<", "<=", "==", ">", ">=", "^", "clone", "leading_zeros_count", "popcount", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trailing_zeros_count", "unsafe_chr", "unsafe_div", "unsafe_mod", "unsafe_shl", "unsafe_shr", "|"]
Float64.methods # => ["!=", "*", "**", "+", "-", "/", "<", "<=", "==", ">", ">=", "ceil", "clone", "fdiv", "floor", "next_float", "prev_float", "round_away", "round_even", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_s", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trunc"]
Proc.methods # => ["==", "===", "arity", "call", "clone", "closure?", "closure_data", "hash", "internal_representation", "partial", "pointer", "to_s"]</syntaxhighlight>
== 脚註 ==
<references />
== 外部リンク ==
* [https://crystal-lang.org/ The Crystal Programming Language] {{---}} 公式サイト
** [https://crystal-lang.org/reference/1.5/ ドキュメント]
*** [https://crystal-lang.org/api/1.5.0/ APIマニュアル]
** [https://play.crystal-lang.org/#/cr Compile & run code in Crystal] {{---}} playground
[[Category:Crystal|*]]
[[Category:プログラミング言語]]
{{NDC|007.64}}
1dg9doqbbs6f381k8gw363gjk50eidx
205811
205810
2022-07-25T05:27:01Z
Ef3
694
/* 網羅性の検査 */ when の代わりに in を使用すると、exhaustive case 式が作成されます。exhaustive case では、必要な in 条件を省略するとコンパイル時にエラーとなります。exhaustive case 式では、when 節と else 節を含むことはできません。
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Crystal (プログラミング言語)}}
本書は、[[w:Crystal (プログラミング言語)|Crystal]]のチュートリアルです。
'''Crystal'''は、Ary Borenszweig、Juan Wajnerman、Brian Cardiffと300人以上の貢献者によって設計・開発された[汎用オブジェクト指向プログラミング言語です<ref>{{Cite web
|url=https://github.com/crystal-lang/crystal/graphs/contributors
|title=Contributors
|accessdate=2022-07-18
|website=github.com
}}</ref>。[[Ruby]] にヒントを得た構文を持ち、静的型チェックを備えた [[コンパイル型言語]]ですが、変数やメソッドの引数の型は一般には不要です。型は高度なグローバル[[型推論]]アルゴリズムによって解決される。<ref>{{Cite web
|url=http://crystal-lang.org/2013/09/23/type-inference-part-1.html
|title=Type inference part 1
|last=Brian J.
|first=Cardiff
|date=2013-09-09
|accessdate=2022-07-18
|website=crystal-lang.org
}}</ref>Crystalは[[Apache License]]バージョン2.0のもと、FOSSとしてリリースされています。
__TOC__
== Hello, World! ==
他の多くのチュートリアルがそうであるように、
私たちもまずはCrystalの世界にあいさつすることから始めましょう。
Rubyとの比較も兼ねて、[[Ruby#Hello, World!]]をそのまま実行してみます。
''hello.cr''というファイルを作り、次のように書いて保存して下さい<ref>Crystalのソースファイルの拡張子は''.cr'' です</ref>。
;hello.cr:<syntaxhighlight lang=Crystal>
puts 'Hello, World!'
</syntaxhighlight>
;コマンドラインでの操作:<syntaxhighlight lang="console">
% cat hello.cr
puts 'Hello, World!'
% crystal hello.cr
In hello.cr:1:6
1 | puts 'Hello, World!'
^
Error: unterminated char literal, use double quotes for strings
% sed -i -e "s@'@Q@g" -e 's@Q@"@g' hello.cr
% cat hello.cr
puts "Hello, World!"
% crystal hello.cr
Hello, World!
</syntaxhighlight>
この1行のスクリプトは、メソッド<code>puts</code> に文字リテラル<code>"Hello, World!"</code>を渡し呼出しています。
このプログラムは、[[Ruby#Hello, World!]]と同じですが、Crystalでは文字列リテラルは <code>"…"</code> で囲うのでそれだけ変更しました。
== プログラミング環境 ==
Crystalのプログラムを作り、コンパイル・実装するには、「オンライン実行環境を使う」・「エディト・コンパイル・実行環境を用意してそれを使う」の2通りの方法があります。
=== オンライン実行環境 ===
公式のオンライン実行環境、 https://play.crystal-lang.org/ があります。
まずは、これを使って本書に例示されているコードを実行してみることをお勧めします。
=== エディト・コンパイル・実行環境 ===
エディタについては本書では触れませんが、プログラミング時間の大半はエディタの操作に費やされるため、良いエディタを選択することが重要です。
Crystal の言語処理系は、 https://crystal-lang.org/install/ から入手します。
自分の、OSやGNU/Linuxであればディストリビューションに合わせてインストールしてください。
また、FreeBSDのように crystal と shards が別パッケージとなっていることもあるので、その場合は shards も追加インストールします。
多くの場合、インストールされた、 crystal はスタティック リンクされているので、ダイナミック リンク版の crystal を入手するには、スタティック リンク版の実行ファイルとソースコードを入手し、スタティック リンク版でソースから crystal をコンパイル・インストールする必要があります。
=== crystal コマンド ===
crystal コマンドは Crystal のコンパイラであると同時に、ビルドツールなどを含んだツールチェインです(プログラミング言語のCrystalは、先頭を大文字、コマンドのcrystalは、先頭を小文字にして区別します)。
[TODO: コマンドラインツール crystal の解説。 crystal ファイル名 は crystal run ファイル名 の短縮形で、インタープリタ的な実行…ではなく、内部ビルドツールでコンパイル・実行を行う]
== Ruby との違い ==
Crystalは、Rubyに触発された構文を持つものの、Rubyとの互換性をゴールに定めては'''いません'''。
このため、細部を見ると仕様に差異があり、Rubyのソースコードをcrystalに掛けても前節の 'Hello World' の様にコンパイルに失敗することがあります。
また、コンパイルできても実行結果に違いが出ることがあります。
ここでは、Ruby との違いについて実際のコードと双方の結果を比較することで、差異についての理解を深めていきます。
=== 整数型の特性 ===
;大きな整数:<syntaxhighlight lang=Crystal>
p 2 ** 999
p (2 ** 999).class
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
Integer
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
Unhandled exception: Arithmetic overflow (OverflowError)
from /usr/local/share/crystal/share/crystal/src/int.cr:295:9 in '**'
from pow.cr:1:1 in '__crystal_main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:101:7 in 'main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:127:3 in 'main'
from /usr/local/lib64/libc.so.6 in '__libc_start_main'
from /usr/local/.cache/crystal/crystal-run-pow.tmp in '_start'
from ???
</syntaxhighlight>
: Ruby の整数は、桁あふれが起こると自動的に多倍長整数に型変換されるので、継ぎ目なしに大きな数を扱うアルゴルズムが使えます。
: Crystal の整数は、固定長です(大きさについては[[#リテラルと型|後述]])。なので大きな答えになる式を評価すると桁あふれが生じます。桁あふれが生じますが、C言語のように寡黙に処理を続けるのではなく、実行時に例外(OverflowError)が上がるので、例外を捕捉し然るべき処置を施すことが可能です。
==== BigInt ====
<code>big</code> を <code>require</code> すると <code>BigInt</code> が使えるようになります。
;BigInt:<syntaxhighlight lang=Crystal>
require "big"
p BigInt.new(2) ** 999
p (BigInt.new(2) ** 999).class
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
BigInt
</syntaxhighlight>
: BigIntはプリミティブではなので、リテラル表現はありません。また、
::<syntaxhighlight lang=Crystal>
n : BigInt = 2
</syntaxhighlight>
::<syntaxhighlight lang=console>
Error: type must be BigInt, not Int32
</syntaxhighlight>
:: のように型アノテーションすることも出来ません。
=== リテラルと型 ===
;様々なリテラルと型:<syntaxhighlight lang=Crystal>
[nil, false, true, 42, 2.73, 'Q', "string", [1,2,3], {a:1, b:2}].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
[nil, NilClass]
[false, FalseClass]
[true, TrueClass]
[42, Integer]
[2.73, Float]
["Q", String]
["string", String]
[[1, 2, 3], Array]
[{:a=>1, :b=>2}, Hash]
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
[nil, Nil]
[false, Bool]
[true, Bool]
[42, Int32]
[2.73, Float64]
['Q', Char]
["string", String]
[[1, 2, 3], Array(Int32)]
[{a: 1, b: 2}, NamedTuple(a: Int32, b: Int32)]
</syntaxhighlight>
: Crystal の整数は Int32、浮動小数点数は Float64 です。
;サイズを指定した数リテラル:<syntaxhighlight lang=Crystal>
[1_i64, 2_u32, 3_u64, 4_i32, 5_i16, 6_u8, 7_i128, 8_u128, 3.14_f32, 1.44_f64].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;ruby:Rubyでは、サーフィックスの付いた数値リテラルは無効
;crystalの実行結果:<syntaxhighlight lang="console">
[1, Int64]
[2, UInt32]
[3, UInt64]
[4, Int32]
[5, Int16]
[6, UInt8]
[7, Int128]
[8, UInt128]
[3.14, Float32]
[1.44, Float64]
</syntaxhighlight>
: Crystal では、数値リテラルに _ で始まるサーフィックスを付け { i:符号付き整数, u:符号なし整数, f:浮動小数点数 } と { 8,16,32,64,128 } のビット幅の組合せです<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/literals/ Literals]</ref>。
=== for式がない ===
Crystal には、Ruby にはある for式がありません。
;Rubyのfor式の構文:<syntaxhighlight lang="ruby">
for 変数 in コレクション
文
end
</syntaxhighlight>
:コレクションは Range, Array, Hash など内部構造を持つオブジェクトです。
:for式は、最後に評価した値を返すので、for'''式'''です。
;for式のeachメソッドによる置換え:<syntaxhighlight lang="ruby">
for x in [ 2, 3, 5, 7, 11 ] do
p x
end
# ↓
[ 2, 3, 5, 7, 11 ].each do | x |
p x
end
</syntaxhighlight>
: の様にコレクションの each メソッドで置換え可能なので、Rubyからの移植でも小規模な書換えで済みます<ref>[https://github.com/crystal-lang/crystal/issues/830 "For" Loop support #830]</ref>(後述のマクロで実装できないかと思いましたが、いまのところ無理のようです)。
また loop 式もありませんが while true; … end で間に合います。Ruby では while 式の条件の次に do が置けますが、Crystal では置けません。
=== eval()がない ===
Crystal には eval() はありません。
Crystalはコンパイル型言語ですので、無理もないことです。
もし、Crystal で eval() を実装しようとすると、Common Lisp の様にインタープリターを丸ごとランタイムに含む必要があります。
これはリーズナブルな選択ではありません。
Crystal では、eval() が必要なケースに(限定的ですが)マクロを使うことで実現出来る可能性があります。
=== マクロ ===
Crystalには、Rubyにはないマクロがあります<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/macros/ Macros - Crystal]</ref>。Rubyは実行時にすべてのオブジェクトにアクセス出来て、メソッド生やし放題なのでマクロは必要ありませんが、Crystalはコンパイル時に型やメソッドを確定する必要があり、特にメソッドジェネレターとしてのマクロにニーズがあります。また、テンプレート言語的なマクロなので、環境変数による条件分岐や、コンテナを渡し繰返し処理する構文もあります(面白いことにマクロには for 文があり、反対にマクロの中では、eachメソッドは使えません)。マクロには <code><nowiki>{{</nowiki>attr.id}}</code> の様にASTへのアクセス手順が用意されており、半ば言語を拡張するようなアプローチを取ることも出来ます。
[TODO:ASTについての解説;コラム向き?]
;マクロを使ったattr_accessorのイミュレーション:<syntaxhighlight lang=crystal>
class Point
def initialize(@x : Int32, @y : Int32)
end
# macro定義
macro attr_accessor(*attrs)
{% for attr in attrs %}
def {{attr.id}}() @{{attr.id}} end
def {{attr.id}}=(var) @{{attr.id}} = var end
{% end %}
end
# macro呼出し
attr_accessor :x, :y
end
pt = Point.new(20, 30)
p [pt.x, pt.y]
t = pt.x
pt.x = pt.y
pt.y = t
p [pt.x, pt.y]
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
[20, 30]
[30, 20]
</syntaxhighlight>
: Ruby には、attr_accessor と言う「クラスのメンバーのアクセサーを自動生成するメソッド」がありますが、Crystalにはないようなので、マクロで実装しました。
:: attr_accessor :name からは
::<syntaxhighlight lang=ruby>
def name() @name end
def name=(val) @name = val end
</syntaxhighlight>相当のコードが生成されます。
[TODO:マクロの機能と構文の説明 *の付いた引数、 <nowiki>{{</nowiki>引数}}、{% … %} 構文]
==== マクロ p! ====
メソッド p は、与えられた「式」の inspaect() の返す値を puts しますが、マクロ p! は、それに先んじて(評価前の)「式」を表示します<ref>[https://crystal-lang.org/api/1.5.0/Crystal/Macros.html#p%21%28%2Aexpressions%29%3ANop-instance-method def p!(*expressions) : Nop]</ref>。
;p!の例:<syntaxhighlight lang=crystal>
x, y = true, false
p! x,y,x && y, x || y, x ^ y, !x, x != y, x == y
ary = [ 1, 2, 3 ]
p! ary
p! ary.map(&. << 1)
p! ary.map(&.to_f)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
x # => true
y # => false
x && y # => false
x || y # => true
x ^ y # => true
!x # => false
x != y # => true
x == y # => false
ary # => [1, 2, 3]
ary.map(&.<<(1)) # => [2, 4, 6]
ary.map(&.to_f) # => [1.0, 2.0, 3.0]
</syntaxhighlight>
===== 入れ子のp! =====
マクロ p! は入れ子に出来ます。また、一旦ASTに変換してから再度ソースコードに変換するので、等価な別の構文に変換されることがあります。
;入れ子のp!:<syntaxhighlight lang=crystal>
p! (
100.times{|i|
p! i
break i if i > 12
}
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(100.times do |i|
p!(i)
if i > 12
break i
end
end) # => i
# => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
i # => 6
i # => 7
i # => 8
i # => 9
i # => 10
i # => 11
i # => 12
i # => 13
13
</syntaxhighlight>
=== クラス ===
==== シンプルなクラス ====
;シンプルなクラス:<syntaxhighlight lang=crystal highlight="2" line>
class Hello
def initialize(@name : String = "World")
end
def greeting
puts "Hello #{@name}!"
end
end
hello = Hello.new()
hello.greeting
universe = Hello.new("Universe")
universe.greeting
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Hello World!
Hello Universe!
</syntaxhighlight>
:;初期化メソッド
:: <syntaxhighlight lang=crystal line start=4>
def initialize(@name : String = "World")
end
</syntaxhighlight>
::Rubyであれば
:: <syntaxhighlight lang=ruby line start=4>
def initialize(name = "World")
@name = name
end
</syntaxhighlight>
::とするところですが、Crystalでは、型アノテーション <code> : String</code> を使い、引数の型を限定しました。
::また、(@ 付きの)アトリビュート名を仮引数にすると、そのままアトリビュート(a.k.a. インスタンス変数)に仮引数が代入されます。
::これは、C++のコンストラクターのメンバー初期化リストと同じアイディアですが、Crystalではインスタンス変数に @ が前置されるので、仮引数に @ が出現すればインスタンス変数の初期値だと自明で、聡明な選択です。
==== 都市間の大圏距離 ====
[[Ruby#ユーザー定義クラス]]の都市間の大圏距離を求めるメソッドを追加した例を、Crystalに移植しました。
;都市間の大圏距離:<syntaxhighlight lang=crystal highlight=”2,7,12” line>
class GeoCoord
getter :longitude, :latitude
def initialize(@longitude : Float64, @latitude : Float64)
end
def to_s(io)
ew, ns = "東経", "北緯"
long, lat = @longitude, @latitude
ew, long = "西経", -long if long < 0.0
ns, lat = "南緯", -lat if lat < 0.0
io << "(#{ew}: #{long}, #{ns}: #{lat})"
end # https://github.com/crystal-lang/crystal/issues/259
def distance(other)
i, r = Math::PI / 180, 6371.008
Math.acos(Math.sin(@latitude*i) * Math.sin(other.latitude * i) +
Math.cos(@latitude*i) * Math.cos(other.latitude * i) * Math.cos(@longitude * i - other.longitude * i)) * r
end
end
# メソッドの先頭を大文字に出来ないのでクラス名のメソッドは作ることが出来ない
# def GeoCoord(lng : Float64, lat : Float64)
# GeoCoord.new(lng, lat)
# end
Sites = {
"東京駅": GeoCoord.new(139.7673068, 35.6809591),
"シドニー・オペラハウス": GeoCoord.new(151.215278, -33.856778),
"グリニッジ天文台": GeoCoord.new(-0.0014, 51.4778),
}
Sites.each { |name, gc|
puts "#{name}: #{gc}"
}
puts ""
keys, len = Sites.keys, Sites.size
keys.each_with_index { |x, i|
y = keys[(i + 1) % len]
puts "#{x} ⇔ #{y}: #{Sites[x].distance(Sites[y])} [km]"
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
東京駅: (東経: 139.7673068, 北緯: 35.6809591)
シドニー・オペラハウス: (東経: 151.215278, 南緯: 33.856778)
グリニッジ天文台: (西経: 0.0014, 北緯: 51.4778)
東京駅 ⇔ シドニー・オペラハウス: 7823.269299386704 [km]
シドニー・オペラハウス ⇔ グリニッジ天文台: 16987.2708377249 [km]
グリニッジ天文台 ⇔ 東京駅: 9560.546566490015 [km]
</syntaxhighlight>
:Crystal には、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> はありませんが、標準ライブラリーのマクロに <syntaxhighlight lang=crystal inline> getter </syntaxhighlight>があるので
:: <syntaxhighlight lang=crystal line start=2>
getter :longitude, :latitude
</syntaxhighlight>
::としました。
::将来、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> が実装される可能性はありますが、姉妹品の<syntaxhighlight lang=crystal inline> setter </syntaxhighlight> との併用が下位互換性を考えると確実です。
: to_s は、Ruby ならば
:: <syntaxhighlight lang=ruby line start=7>
def to_s()
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
"(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
:: ですが、Crystalでは追加の引数 <var>io</var> が必要で
:: <syntaxhighlight lang=ruby line start=7>
def to_s(io)
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
io << "(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
: Ruby にはクラス名と同じ名前のメソッドで .new を呼出す文化があるのですが、Crystalはメソッドの先頭を大文字に出来ないので、これは見送りました。
==== 包含と継承 ====
[[JavaScript/クラス#包含と継承]]を、Rubyに移植した[[Ruby#包含と継承]]を、Crystalに移植しました。
;包含と継承の例:<syntaxhighlight lang=crystal line>
class Point
def initialize(@x = 0, @y = 0)
end
def inspect(io)
io << "x:#{@x}, y:#{@y}"
end
def move(dx = 0, dy = 0)
@x, @y = @x + dx, @y + dy
self
end
end
class Shape
def initialize(x = 0, y = 0)
@location = Point.new(x, y)
end
def inspect(io)
@location.inspect(io)
end
def move(x, y)
@location.move(x, y)
self
end
end
class Rectangle < Shape
def initialize(x = 0, y = 0, @width = 0, @height = 0)
super(x, y)
end
def inspect(io)
super(io)
io << ", width:#{@width}, height:#{@height}"
end
end
rct = Rectangle.new(12, 32, 100, 50)
p! rct,
rct.is_a?(Rectangle),
rct.is_a?(Shape),
rct.is_a?(Point),
rct.move(11, 21)
(END)</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
rct # => x:12, y:32, width:100, height:50
rct.is_a?(Rectangle) # => true
rct.is_a?(Shape) # => true
rct.is_a?(Point) # => false
rct.move(11, 21) # => x:23, y:53, width:100, height:50
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy inclusion-and-inheritance.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (16 bytes)
. @location : Point (8 bytes)
|
+- class Rectangle (24 bytes)
@width : Int32 (4 bytes)
@height : Int32 (4 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
===== superclass と subclasses =====
Crystal には、RubyのClassにあるメソッド superclass と subclasses がないので、マクロで実装しました。
;superclass と subclasses:<syntaxhighlight lang=crystal line>
class Class
def self.superclass
{{ @type.superclass }}
end
def self.subclasses : Array(self.class)
{{ @type.subclasses }}.map(&.as(self.class))
end
def self.all_subclasses : Array(self.class)
{% begin %}
[{{ @type.all_subclasses.join(",").id }}] of self.class
{% end %}
end
end
class A end
class AA < A end
class AAA < AA end
class AAB < AA end
class AB < A end
p! A,
A.subclasses,
A.all_subclasses,
AAA.superclass,
A.superclass
c = AAA
while !c.is_a? Nil
p! c.superclass
c = c.superclass
end</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
A # => A
A.subclasses # => [AA, AB]
A.all_subclasses # => [AA, AAA, AAB, AB]
AAA.superclass # => AA
A.superclass # => Reference
c.superclass # => AA
c.superclass # => A
c.superclass # => Reference
c.superclass # => Object
c.superclass # => nil
</syntaxhighlight>
==== 抽象クラス ====
[[Java/抽象クラス]]を、Crystalに移植しました。
;抽象クラスの宣言:<syntaxhighlight lang=Java>
abstract class クラス名
#
end
</syntaxhighlight>
: このクラス名は、 .new でインスタンス化出来ません。
:: Error: can't instantiate abstract class クラス名
: となります。
:インスタンス化することは出来ませんが、抽象クラスを別のクラスが継承する事は出来ます。
:また、抽象クラスを <code>super()</code> を使うことでメソッドを呼び出せるので、抽象メソッドではないメソッド(具象メソッド)を持つことも、インスタンス変数も持つことも出来ます。
:'''抽象クラスの例'''では、Shapeのinitializeメソッドが抽象クラスの具象メソッドとなっています。
;抽象メソッドの宣言:<syntaxhighlight lang=Java>
abstract def メソッド名
</syntaxhighlight>
: 派生先のクラスで、「メソッド名」を定義(def)し忘れると
:: Error: abstract `def クラス名#メソッド名()` must be implemented by クラス名
: となります
;抽象クラスの例:<syntaxhighlight lang=crystal line>
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
class Recrangle < Shape
def initialize(x, y, @w = 0.0, @h = 0.0)
super(x, y)
end
def to_s(io)
io << "Rectanle(#{@x}, #{@y}, #{@w}, #{@h})"
end
def area
@w * @h
end
end
class Circle < Shape
def initialize(x, y, @r = 0.0)
super(x, y)
end
def to_s(io)
io << "Circle(#{@x}, #{@y}, #{@r})"
end
def area
3.1425926536 * @r * @r
end
end
shapes = [
Square.new(5.0, 10.0, 15.0),
Recrangle.new(13.0, 23.0, 20.0, 10.0),
Circle.new(3.0, 2.0, 20.0),
] of Shape
shapes.each do |shape|
puts("#{shape}: #{shape.area}")
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Square(5.0, 10.0, 15.0): 225.0
Rectanle(13.0, 23.0, 20.0, 10.0): 200.0
Circle(3.0, 2.0, 20.0): 1257.03706144
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy abstract.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (24 bytes)
. @x : Float64 (8 bytes)
. @y : Float64 (8 bytes)
|
+- class Circle (32 bytes)
| @r : Float64 (8 bytes)
|
+- class Recrangle (40 bytes)
| @w : Float64 (8 bytes)
| @h : Float64 (8 bytes)
|
+- class Square (32 bytes)
@wh : Float64 (8 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
: 「包含と継承の例」と比べると、ShapeとRectangleが同じ階層にあることがわかると思います。
[TODO:virtual class::いい例がない]
== キーワード ==
Crystalのキーワード( ''keywords'' ) は、以下の通り。
<code>abstract</code> <code>alias</code> <code>as</code> <code>asm</code> <code>begin</code> <code>break</code> <code>case</code> <code>class</code> <code>def</code> <code>do</code> <code>else</code> <code>elsif</code> <code>end</code> <code>ensure</code> <code>enum</code> <code>extend</code> <code>for</code> <code>fun</code> <code>if</code> <code>include</code> <code>instance_sizeof</code> <code>lib</code> <code>macro</code> <code>module</code> <code>next</code> <code>of</code> <code>out</code> <code>pointerof</code> <code>private</code> <code>protected</code> <code>rescue</code> <code>return</code> <code>require</code> <code>select</code> <code>sizeof</code> <code>struct</code> <code>super</code> <code>then</code> <code>type</code> <code>typeof</code> <code>uninitialized</code> <code>union</code> <code>unless</code> <code>until</code> <code>when</code> <code>while</code> <code>with</code> <code>yield</code>
<!--
<code>__DIR__</code> <code>__END_LINE__</code> <code>__FILE__</code> <code>__LINE__</code>
-->
== 演算子 ==
Crystalは、1つ、2つ、または3つのオペランドを持つ数多くの演算子をサポートしています<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/operators.html Operators]access-date:2022-07-22</ref>。
演算子式は、実際にはメソッド呼び出しとしてパースされます。例えば、<code>a + b</code> は <code>a.+(b)</code> と意味的に同じで、引数 b を持つ a のメソッド + を呼び出すことになります。
{| class="wikitable"
|+ 演算子の優先度
!種類
!演算子
|-
|インデックス アクセサー
|<code>[]</code>, <code>[]?</code>
|-
|単項
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>, <code>!</code>, <code>~</code>
|-
|指数
|<code>**</code>, <code>&**</code>
|-
|乗除
|<code>*</code>, <code>&*</code>, <code>/</code>, <code>//</code>, <code>%</code>
|-
|加減
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>
|-
|シフト
|<code><<</code>, <code>>></code>
|-
|ビット間 AND
|<code>&</code>
|-
|ビット間 OR/XOR
|<code><nowiki>|</nowiki></code>,<code>^</code>
|-
|等値
|<code>==</code>, <code>!=</code>, <code>=~</code>, <code>!~</code>, <code>===</code>
|-
|比較
|<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>, <code><=></code>
|-
|論理 AND
|<code>&&</code>
|-
|論理 OR
|<code><nowiki>||</nowiki></code>
|-
|Range
|<code>..</code>, <code>...</code>
|-
|条件
|<code>?:</code>
|-
|代入
|<code>=</code>, <code>[]=</code>, <code>+=</code>, <code>&+=</code>, <code>-=</code>, <code>&-=</code>, <code>*=</code>, <code>&*=</code>, <code>/=</code>, <code>//=</code>, <code>%=</code>, <code><nowiki>|=</nowiki></code>, <code>&=</code>,<code>^=</code>,<code>**=</code>,<code><<=</code>,<code>>>=</code>, <code><nowiki>||=</nowiki></code>, <code>&&=</code>
|-
|スプラット
|<code>*</code>, <code>**</code>
|}
== 制御構造 ==
'''[[w:制御構造|制御構造]]'''(せいぎょこうぞう、''control flow'')とは、「順次」「分岐」「反復」という基本的な処理のことを言います。
{{コラム|Crystalの真理値|2=
制御構造は「条件式」が真であるか偽であるかによって分岐や反復の振る舞いが変わります。
では「条件式」が真・偽はどの様に決まるのでしょう?
Crystalでは <code>false</code> あるいは <code>nil</code> であると偽、それ以外が真です。
なので <code>0</code> も <code>[]</code>(空のArray) も <code>{}</code>(空のNamedTuple)も真です。
}}
=== 条件分岐 ===
Crystalの条件分岐には、[[#if|if]], [[#until|until]] と [[#case|case]]の3つの構文があります。
==== if ====
'''[[w:if|if]]'''は条件式によって実行・否を切り替える構造構文で、評価した式の値を返すので条件演算子でもあります。
;ifの例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
if a < 0
puts "minus"
elsif a > 0
puts "plus"
elsif a == 0
puts "zero"
else
puts a
end
p! (
if a < 0
"minus"
elsif a > 0
"plus"
elsif a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(if a < 0
"minus"
else
if a > 0
"plus"
else
if a == 0
"zero"
else
a
end
end
end) # => NaN
</syntaxhighlight>
:; elsif節:ifは、オプショナルな elsif 節を設け、条件式が偽であった時に別の条件に合致した処理を実行させることが出来ます。
:; else節:ifは、オプショナルな else 節を設け、条件式が偽であった時に処理を実行させることが出来ます。
: ifは値を返すので、メソッドの実引数に使うことが出来ますし、代入演算の右辺にも使えます。
==== 後置のif ====
Crystalには、RubyやPerlのような後置のifがあります。
;後置のifの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" if n == 0
puts "nは1" if n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは0
</syntaxhighlight>
==== unless====
'''unless'''(アンレス)は条件式によって実行・否を切り替える構造構文ですが、ifとは条件式に対する挙動が逆です。
;unless文の例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
unless a == 0
puts "Non-zero"
else
puts a
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Non-zero
</syntaxhighlight>
:; else節 : unless文は、オプショナルな else 節を設け、条件式が真であった時に処理を実行させることが出来ます。
::また、unless文は elsif 節は持てません。
==== 後置のunless ====
Crystalには、RubyやPerlのような後置のunlessがあります。
;後置のunlessの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" unless n == 0
puts "nは1" unless n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは1ではない
</syntaxhighlight>
==== case ====
caseは、複数の条件式によって処理を降る分ける用途の為に用意されています。
;caseの例:<syntaxhighlight lang=crystal line>
n = 2
case n
when 1
puts "one"
when 2
puts "two"
when 3
puts "three"
else
puts "other"
end
p! (
case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
two
(case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end) # => "two"</syntaxhighlight>
:C言語系のswitch文に慣れた人はbreakがないことに気がつくと思います。Crystalのcaseはfall throughしませんし、fall throughさせる方法もありません。
===== when節が定数でなく式を受付けます =====
[[#if|if]]を使ったコードをcaseに書き換えてみましょう。
;case の式の省略:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
case
when a < 0
puts "minus"
when a > 0
puts "plus"
when a == 0
puts "zero"
else
puts a
end
p! (
case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end) # => NaN
</syntaxhighlight>
このコードは when 節の式の値とcaseの式を <code>===</code> で比較し、最初に一致した when に対応する式が実行される事を利用しています。
===== 型による分岐 =====
when 節が式ではなく型であった場合、caseの式を <code>is_a?</code> で評価し、最初に一致した when に対応する式が実行されます。
;型による分岐:<syntaxhighlight lang=crystal line>
p! 0.class,
0.is_a?(Object),
0.is_a?(Int32),
0.is_a?(Number),
0.is_a?(String)
case 0
when String
puts "String"
when Number
puts "Number"
when Int32
puts "Int32"
when Object
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0.class # => Int32
0.is_a?(Object) # => true
0.is_a?(Int32) # => true
0.is_a?(Number) # => true
0.is_a?(String) # => false
Number
</syntaxhighlight>
暗黙のオブジェクト構文を使うと
:<syntaxhighlight lang=crystal line>
case 0
when .is_a?(String)
puts "String"
when .is_a?(Number)
puts "Number"
when .is_a(Int32)
puts "Int32"
when .is_a(Object)
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
:と書くことが出来ます。
:: メソッドは、.is_a? に限定しないので、 .odd? .even? .include? など Bool を返すメソッドなら何でも使えます。
when に対応する式は、1つのことが珍しくないので、その場合は省略可能な then を補うと、1行で書けます。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
[TODO:タプルとダミー識別子 _ ]
===== 網羅性の検査 =====
when の代わりに in を使用すると、exhaustive case 式が作成されます。exhaustive case では、必要な in 条件を省略するとコンパイル時にエラーとなります。exhaustive case 式では、when 節と else 節を含むことはできません。
;Enumの網羅性チェック(網羅不完全):<syntaxhighlight lang=crystal line highlight=11>
enum Colours
Red
Green
Blue
end
colour : Colours = Colours::Red
q = case colour
in Colours::Red then "赤"
in .green? then "緑"
# in .blue? then "青"
end
p q
</syntaxhighlight>
;コンパイルエラー:<syntaxhighlight lang="text">
Showing last frame. Use --error-trace for full trace.
In enumcase.cr:8:5
8 | q = case colour
^
Error: case is not exhaustive for enum Colours.
Missing members:
- Blue
</syntaxhighlight>
: case - in 式の in が列挙型の要素を網羅していないと、コンパイル時にこの様にエラーになります。
:: Colours::Red と .red? は同義です(enum では、要素名を小文字にし最後に ? が付いたメソッドが生えてきます)。
;Enumの網羅性チェック(網羅完全):<syntaxhighlight lang=crystal line highlight=11>
enum Colours
Red
Green
Blue
end
colour : Colours = Colours::Red
q = case colour
in Colours::Red then "赤"
in .green? then "緑"
in .blue? then "青"
end
p q
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
"赤"
</syntaxhighlight>
[TODO:短絡評価 && || ]
=== 繰返し ===
Crystalには、他のプログラミング言語のような[[#繰返し構文|繰返し構文]]と、[[#イテレーターメソッド|イテレーターメソッド]]があります。
==== 繰返し構文 ====
Crystalの繰返し構文には、while と untilの2つがあります<ref>for も do-while も loop もありません。</ref>。
===== while =====
while(ホワイル)は条件が'''真'''である間、式を実行しつづけます。
;構文:<syntaxhighlight lang=crystal>
while 条件式
式1
式2
:
式n
end
</syntaxhighlight>
: Rubyと違い、条件式の後ろに <code>do</code> をつけることは出来ません。
;while文のコード例:<syntaxhighlight lang=crystal line>
i = 0
p! (
while i < 10
p! i
i += 1
break i if i > 5
end
)
</syntaxhighlight>
: 2行目の <code>i < 5</code>が真の間、次の2行を繰返します。
: 4行目の <code>i += 1</code> は <code>i = i + 1</code> の構文糖
;実行結果:<syntaxhighlight lang="text">
(while i < 10
p!(i)
i = i + 1
if i > 5
break i
end
end)# =>
i # => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
6
</syntaxhighlight>
===== until =====
until(アンティル)は条件が'''偽'''である間、式を実行しつづけます。whileとは条件に対する挙動が逆です。
;構文:<syntaxhighlight lang=crystal>
until 条件式 [ do ]
文1
文2
:
文n
end
</syntaxhighlight>
: <code>do</code> は省略できます。
;untilのコード例:<syntaxhighlight lang=crystal line>
i = 0
until i == 3
puts i
i += 1
end
</syntaxhighlight>
: 2行目の <code>i == 3</code>が偽の間、次の2行を繰返します。
;実行結果:<syntaxhighlight lang="text">
0
1
2
</syntaxhighlight>
===== for =====
Crystalにはforがありませんが、コレクションのイテレーションメソッドを使うことで繰返しを簡素に実現出来ます。
==== Rangeオブジェクト ====
Rangeオブジェクトは、整数の区間を表し範囲演算子 <code>開始 ... 終了</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
rng = 1..3
puts rng.class
rng.each do | n |
puts "#{n}番";
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Range(Int32, Int32)
1番
2番
3番
</syntaxhighlight>
==== Arrayオブジェクト ====
Arrayオブジェクトは、任意の Crystal オブジェクトを要素として持つことができます。
配列式<code>[要素1, 要素2, … 要素n]</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
animals = ["ネコ", "金魚", "ハムスター"]
puts animals.class
animals.each do | animal |
puts "動物 #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Array(String)
動物 ネコ
動物 金魚
動物 ハムスター
</syntaxhighlight>
==== NamedTupleオブジェクト ====
NamedTupleオブジェクトは、任意の Crystal オブジェクトをキーに、任意の Crystal オブジェクトを値に持つことができる連想配列です。
NamedTuple式<code>{キー1 => 値1, キー2 => 値2, キーn => 値n}</code> で生成します。
また、キーが Symbol の場合
NamedTuple式<code>{キー1: 値1, キー2: 値2, キーn: 値n}</code> で生成することが出来ます。
;コード:<syntaxhighlight lang=crystal>
animals = {cat: "ネコ", gold_fish: "金魚", hamster: "ハムスター"}
puts animals.class
animals.each do | en, animal |
puts "動物 #{en}: #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NamedTuple(cat: String, gold_fish: String, hamster: String)
動物 cat: ネコ
動物 gold_fish: 金魚
動物 hamster: ハムスター
</syntaxhighlight>
このように、Crystalではforがなくてもコレクションのメソッドで同様の処理を実現できます。
===== loop =====
loop、ありません。
while true で代用します。
;loopの代用コード例:<syntaxhighlight lang=crystal line>
i = 1
while true
puts "0b%b" % i
i <<= 1
break if i > 2**8
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0b1
0b10
0b100
0b1000
0b10000
0b100000
0b1000000
0b10000000
0b100000000
</syntaxhighlight>
:5行目の、<code>break if i > 2**8</code>でループを脱出するようにしています。この様に break や return あるいは例外が上がらないとループは永久に終わりません。
:このコードは、Crystalにはない do-while文を模倣する例にもなっています。
==== イテレーターメソッド ====
===== Integer#times =====
Integer#timesは与えられたブロックをオブジェクトの示す整数値回くりかえします。
:コード<syntaxhighlight lang=crystal>
3.times{ puts "Hello, world!" }
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello, world!
Hello, world!
Hello, world!
</syntaxhighlight>
;繰返したい処理が2行以上ある場合:<syntaxhighlight lang=crystal>
3.times {
puts "Hello"
puts "World"
puts ""
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello
World
Hello
World
Hello
World
</syntaxhighlight>
;ループ変数を使た例:<syntaxhighlight lang=crystal>
3.times do |i|
puts "#{i}の倍は#{2 * i}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0の倍は0
1の倍は2
2の倍は4
</syntaxhighlight>
;ブロックを伴わないtimesメソッド:<syntaxhighlight lang=crystal>
iter = 3.times
puts iter.class
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
# puts iter.next # `next': StopIteration: iteration reached an end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Int::TimesIterator(Int32)
iter.next # => 0
iter.next # => 1
iter.next # => 2
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
</syntaxhighlight>
: Integer#times にブロックを渡さないと、Int::TimesIterator([T])オブジェクトが返ります。
: Int::TimesIterator([T])オブジェクトは外部イテレーターと呼ばれnextメソッドで反復を行えます。
== メソッド ==
=== クラスのメソッド一覧 ===
Crystal には、Objectクラスにmethodsメソッドがないので、マクロで実装しました。
;RubyのObject#methods:<syntaxhighlight lang=ruby>
p Object.methods.sort,
Integer.methods.sort,
Float.methods.sort,
Array.methods.sort,
Range.methods.sort
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :sqrt, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :[], :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
</syntaxhighlight>
;Crystalに実装したmethodsマクロ:<syntaxhighlight lang=crystal>
class Object
macro methods
{{ @type.methods.map(&.name.stringify).sort.uniq }}
end
end
p! Object.methods,
Reference.methods,
Array.methods,
Box.methods,
Channel.methods,
Deque.methods,
Dir.methods,
Exception.methods,
ArgumentError.methods,
DivisionByZeroError.methods,
IndexError.methods,
InvalidByteSequenceError.methods,
Fiber.methods,
Hash.methods,
IO.methods,
File.methods,
Mutex.methods,
PrettyPrint.methods,
Process.methods,
Regex.methods,
String.methods,
Thread.methods,
Bool.methods,
Int32.methods,
Float64.methods,
Proc.methods
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
Object.methods # => ["!=", "!~", "==", "===", "=~", "class", "crystal_type_id", "dup", "hash", "in?", "inspect", "itself", "not_nil!", "pretty_inspect", "pretty_print", "tap", "to_s", "try", "unsafe_as"]
Reference.methods # => ["==", "dup", "exec_recursive", "exec_recursive_clone", "hash", "inspect", "object_id", "pretty_print", "same?", "to_s"]
Array.methods # => ["&", "*", "+", "-", "<<", "<=>", "==", "[]", "[]=", "[]?", "calculate_new_capacity", "check_needs_resize", "check_needs_resize_for_unshift", "clear", "clone", "compact", "compact!", "concat", "delete", "delete_at", "dup", "each_repeated_permutation", "fill", "first", "flatten", "increase_capacity", "increase_capacity_for_unshift", "index", "initialize", "insert", "inspect", "internal_delete", "last", "map", "map_with_index", "needs_resize?", "pop", "pop?", "pretty_print", "product", "push", "reject!", "remaining_capacity", "repeated_permutations", "replace", "reset_buffer_to_root_buffer", "resize_if_cant_insert", "resize_to_capacity", "resize_to_capacity_for_unshift", "reverse", "root_buffer", "rotate", "rotate!", "select!", "shift", "shift?", "shift_buffer_by", "shift_when_not_empty", "shuffle", "size", "size=", "skip", "sort", "sort!", "sort_by", "sort_by!", "to_a", "to_lookup_hash", "to_s", "to_unsafe", "to_unsafe_slice", "transpose", "truncate", "uniq", "uniq!", "unsafe_fetch", "unsafe_put", "unshift", "unstable_sort", "unstable_sort!", "unstable_sort_by", "unstable_sort_by!", "|"]
Box.methods # => ["initialize", "object"]
Channel.methods # => ["close", "closed?", "dequeue_receiver", "dequeue_sender", "initialize", "inspect", "pretty_print", "receive", "receive?", "receive_impl", "receive_internal", "receive_select_action", "receive_select_action?", "send", "send_internal", "send_select_action"]
Deque.methods # => ["+", "<<", "==", "buffer", "clear", "clone", "concat", "delete", "delete_at", "dup", "each", "halfs", "increase_capacity", "initialize", "insert", "inspect", "internal_delete", "pop", "pop?", "pretty_print", "push", "reject!", "rotate!", "select!", "shift", "shift?", "size", "size=", "to_s", "unsafe_fetch", "unsafe_put", "unshift"]
Dir.methods # => ["children", "close", "each", "each_child", "entries", "initialize", "inspect", "path", "pretty_print", "read", "rewind", "to_s"]
Exception.methods # => ["backtrace", "backtrace?", "callstack", "callstack=", "cause", "initialize", "inspect", "inspect_with_backtrace", "message", "to_s"]
ArgumentError.methods # => ["initialize"]
DivisionByZeroError.methods # => ["initialize"]
IndexError.methods # => ["initialize"]
InvalidByteSequenceError.methods # => ["initialize"]
Fiber.methods # => ["cancel_timeout", "dead?", "enqueue", "initialize", "inspect", "makecontext", "name", "name=", "next", "next=", "previous", "previous=", "push_gc_roots", "resumable?", "resume", "resume_event", "run", "running?", "stack_bottom", "stack_bottom=", "timeout", "timeout_event", "timeout_select_action", "timeout_select_action=", "to_s"]
Hash.methods # => ["==", "[]", "[]=", "[]?", "add_entry_and_increment_size", "clear", "clear_entries", "clear_impl", "clear_indices", "clone", "compact", "compact!", "compare_by_identity", "compare_by_identity?", "compute_indices_bytesize", "delete", "delete_entry", "delete_entry_and_update_counts", "delete_impl", "delete_linear_scan", "dig", "dig?", "do_compaction", "double_indices_size", "dup", "each", "each_entry_with_index", "each_key", "each_value", "empty?", "entries", "entries_capacity", "entries_full?", "entries_size", "entry_matches?", "fetch", "find_entry", "find_entry_with_index", "find_entry_with_index_linear_scan", "first_entry?", "first_key", "first_key?", "first_value", "first_value?", "fit_in_indices", "get_entry", "get_index", "has_key?", "has_value?", "hash", "indices_malloc_size", "indices_size", "initialize", "initialize_clone", "initialize_clone_entries", "initialize_compare_by_identity", "initialize_copy_non_entries_vars", "initialize_default_block", "initialize_dup", "initialize_dup_entries", "inspect", "invert", "key_for", "key_for?", "key_hash", "keys", "last_entry?", "last_key", "last_key?", "last_value", "last_value?", "malloc_entries", "malloc_indices", "merge", "merge!", "merge_into!", "next_index", "pretty_print", "proper_subset_of?", "proper_superset_of?", "put", "realloc_entries", "realloc_indices", "rehash", "reject", "reject!", "resize", "select", "select!", "set_entry", "set_index", "shift", "shift?", "size", "subset_of?", "superset_of?", "to_a", "to_a_impl", "to_h", "to_s", "transform_keys", "transform_values", "transform_values!", "update", "update_linear_scan", "upsert", "values", "values_at"]
IO.methods # => ["<<", "check_open", "close", "closed?", "decoder", "each_byte", "each_char", "each_line", "encoder", "encoding", "flush", "getb_to_end", "gets", "gets_peek", "gets_slow", "gets_to_end", "has_non_utf8_encoding?", "peek", "peek_or_read_utf8", "peek_or_read_utf8_masked", "pos", "pos=", "print", "printf", "puts", "read", "read_at", "read_byte", "read_bytes", "read_char", "read_char_with_bytesize", "read_fully", "read_fully?", "read_line", "read_string", "read_utf8", "read_utf8_byte", "rewind", "seek", "set_encoding", "skip", "skip_to_end", "tell", "tty?", "utf8_encoding?", "write", "write_byte", "write_bytes", "write_string", "write_utf8"]
File.methods # => ["delete", "initialize", "inspect", "path", "read_at", "size", "truncate"]
Mutex.methods # => ["initialize", "lock", "lock_slow", "synchronize", "try_lock", "unlock"]
PrettyPrint.methods # => ["break_outmost_groups", "breakable", "comma", "current_group", "fill_breakable", "flush", "group", "group_queue", "group_sub", "indent", "initialize", "list", "nest", "newline", "surround", "text"]
Process.methods # => ["channel", "close", "close_io", "copy_io", "ensure_channel", "error", "error?", "exists?", "finalize", "initialize", "input", "input?", "output", "output?", "pid", "signal", "stdio_to_fd", "terminate", "terminated?", "wait"]
Regex.methods # => ["+", "==", "===", "=~", "capture_count", "clone", "dup", "finalize", "hash", "initialize", "inspect", "internal_matches?", "match", "match_at_byte_index", "matches?", "matches_at_byte_index?", "name_table", "options", "source", "to_s"]
String.methods # => ["%", "*", "+", "<=>", "==", "=~", "[]", "[]?", "ascii_only?", "blank?", "byte_at", "byte_at?", "byte_delete_at", "byte_index", "byte_index_to_char_index", "byte_slice", "byte_slice?", "bytes", "bytesize", "calc_excess_left", "calc_excess_right", "camelcase", "capitalize", "center", "char_at", "char_bytesize_at", "char_index_to_byte_index", "chars", "check_no_null_byte", "chomp", "clone", "codepoint_at", "codepoints", "compare", "count", "delete", "delete_at", "downcase", "dump", "dump_char", "dump_hex", "dump_or_inspect", "dump_or_inspect_char", "dump_or_inspect_unquoted", "dump_unquoted", "dup", "each_byte", "each_byte_index_and_char_index", "each_char", "each_char_with_index", "each_codepoint", "each_grapheme", "each_grapheme_boundary", "each_line", "empty?", "encode", "ends_with?", "find_start_and_end", "grapheme_size", "graphemes", "gsub", "gsub_append", "gsub_ascii_char", "has_back_references?", "hash", "hexbytes", "hexbytes?", "includes?", "index", "insert", "insert_impl", "inspect", "inspect_char", "inspect_unquoted", "just", "lchop", "lchop?", "lines", "ljust", "lstrip", "match", "matches?", "partition", "presence", "pretty_print", "rchop", "rchop?", "remove_excess", "remove_excess_left", "remove_excess_right", "reverse", "rindex", "rjust", "rpartition", "rstrip", "scan", "scan_backreferences", "scrub", "single_byte_optimizable?", "size", "size_known?", "split", "split_by_empty_separator", "split_single_byte", "squeeze", "starts_with?", "strip", "sub", "sub_append", "sub_index", "sub_range", "succ", "titleize", "to_f", "to_f32", "to_f32?", "to_f64", "to_f64?", "to_f?", "to_f_impl", "to_i", "to_i128", "to_i128?", "to_i16", "to_i16?", "to_i32", "to_i32?", "to_i64", "to_i64?", "to_i8", "to_i8?", "to_i?", "to_s", "to_slice", "to_u128", "to_u128?", "to_u16", "to_u16?", "to_u32", "to_u32?", "to_u64", "to_u64?", "to_u8", "to_u8?", "to_unsafe", "to_unsigned_info", "to_utf16", "tr", "underscore", "unicode_delete_at", "unsafe_byte_at", "unsafe_byte_slice", "unsafe_byte_slice_string", "upcase", "valid_encoding?"]
Thread.methods # => ["detach", "event_base", "gc_thread_handler", "gc_thread_handler=", "initialize", "join", "main_fiber", "next", "next=", "previous", "previous=", "scheduler", "stack_address", "start", "to_unsafe"]
Bool.methods # => ["!=", "&", "==", "^", "clone", "hash", "to_s", "to_unsafe", "|"]
Int32.methods # => ["!=", "&", "&*", "&+", "&-", "*", "+", "-", "/", "<", "<=", "==", ">", ">=", "^", "clone", "leading_zeros_count", "popcount", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trailing_zeros_count", "unsafe_chr", "unsafe_div", "unsafe_mod", "unsafe_shl", "unsafe_shr", "|"]
Float64.methods # => ["!=", "*", "**", "+", "-", "/", "<", "<=", "==", ">", ">=", "ceil", "clone", "fdiv", "floor", "next_float", "prev_float", "round_away", "round_even", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_s", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trunc"]
Proc.methods # => ["==", "===", "arity", "call", "clone", "closure?", "closure_data", "hash", "internal_representation", "partial", "pointer", "to_s"]</syntaxhighlight>
== 脚註 ==
<references />
== 外部リンク ==
* [https://crystal-lang.org/ The Crystal Programming Language] {{---}} 公式サイト
** [https://crystal-lang.org/reference/1.5/ ドキュメント]
*** [https://crystal-lang.org/api/1.5.0/ APIマニュアル]
** [https://play.crystal-lang.org/#/cr Compile & run code in Crystal] {{---}} playground
[[Category:Crystal|*]]
[[Category:プログラミング言語]]
{{NDC|007.64}}
j0crzgofb55bpp85kzl1be2h073k9dk
205812
205811
2022-07-25T05:33:23Z
Ef3
694
/* Integer#times */ 冗長な例を削除
wikitext
text/x-wiki
{{Pathnav|メインページ|工学|情報技術|プログラミング|frame=1}}
{{Wikipedia|Crystal (プログラミング言語)}}
本書は、[[w:Crystal (プログラミング言語)|Crystal]]のチュートリアルです。
'''Crystal'''は、Ary Borenszweig、Juan Wajnerman、Brian Cardiffと300人以上の貢献者によって設計・開発された[汎用オブジェクト指向プログラミング言語です<ref>{{Cite web
|url=https://github.com/crystal-lang/crystal/graphs/contributors
|title=Contributors
|accessdate=2022-07-18
|website=github.com
}}</ref>。[[Ruby]] にヒントを得た構文を持ち、静的型チェックを備えた [[コンパイル型言語]]ですが、変数やメソッドの引数の型は一般には不要です。型は高度なグローバル[[型推論]]アルゴリズムによって解決される。<ref>{{Cite web
|url=http://crystal-lang.org/2013/09/23/type-inference-part-1.html
|title=Type inference part 1
|last=Brian J.
|first=Cardiff
|date=2013-09-09
|accessdate=2022-07-18
|website=crystal-lang.org
}}</ref>Crystalは[[Apache License]]バージョン2.0のもと、FOSSとしてリリースされています。
__TOC__
== Hello, World! ==
他の多くのチュートリアルがそうであるように、
私たちもまずはCrystalの世界にあいさつすることから始めましょう。
Rubyとの比較も兼ねて、[[Ruby#Hello, World!]]をそのまま実行してみます。
''hello.cr''というファイルを作り、次のように書いて保存して下さい<ref>Crystalのソースファイルの拡張子は''.cr'' です</ref>。
;hello.cr:<syntaxhighlight lang=Crystal>
puts 'Hello, World!'
</syntaxhighlight>
;コマンドラインでの操作:<syntaxhighlight lang="console">
% cat hello.cr
puts 'Hello, World!'
% crystal hello.cr
In hello.cr:1:6
1 | puts 'Hello, World!'
^
Error: unterminated char literal, use double quotes for strings
% sed -i -e "s@'@Q@g" -e 's@Q@"@g' hello.cr
% cat hello.cr
puts "Hello, World!"
% crystal hello.cr
Hello, World!
</syntaxhighlight>
この1行のスクリプトは、メソッド<code>puts</code> に文字リテラル<code>"Hello, World!"</code>を渡し呼出しています。
このプログラムは、[[Ruby#Hello, World!]]と同じですが、Crystalでは文字列リテラルは <code>"…"</code> で囲うのでそれだけ変更しました。
== プログラミング環境 ==
Crystalのプログラムを作り、コンパイル・実装するには、「オンライン実行環境を使う」・「エディト・コンパイル・実行環境を用意してそれを使う」の2通りの方法があります。
=== オンライン実行環境 ===
公式のオンライン実行環境、 https://play.crystal-lang.org/ があります。
まずは、これを使って本書に例示されているコードを実行してみることをお勧めします。
=== エディト・コンパイル・実行環境 ===
エディタについては本書では触れませんが、プログラミング時間の大半はエディタの操作に費やされるため、良いエディタを選択することが重要です。
Crystal の言語処理系は、 https://crystal-lang.org/install/ から入手します。
自分の、OSやGNU/Linuxであればディストリビューションに合わせてインストールしてください。
また、FreeBSDのように crystal と shards が別パッケージとなっていることもあるので、その場合は shards も追加インストールします。
多くの場合、インストールされた、 crystal はスタティック リンクされているので、ダイナミック リンク版の crystal を入手するには、スタティック リンク版の実行ファイルとソースコードを入手し、スタティック リンク版でソースから crystal をコンパイル・インストールする必要があります。
=== crystal コマンド ===
crystal コマンドは Crystal のコンパイラであると同時に、ビルドツールなどを含んだツールチェインです(プログラミング言語のCrystalは、先頭を大文字、コマンドのcrystalは、先頭を小文字にして区別します)。
[TODO: コマンドラインツール crystal の解説。 crystal ファイル名 は crystal run ファイル名 の短縮形で、インタープリタ的な実行…ではなく、内部ビルドツールでコンパイル・実行を行う]
== Ruby との違い ==
Crystalは、Rubyに触発された構文を持つものの、Rubyとの互換性をゴールに定めては'''いません'''。
このため、細部を見ると仕様に差異があり、Rubyのソースコードをcrystalに掛けても前節の 'Hello World' の様にコンパイルに失敗することがあります。
また、コンパイルできても実行結果に違いが出ることがあります。
ここでは、Ruby との違いについて実際のコードと双方の結果を比較することで、差異についての理解を深めていきます。
=== 整数型の特性 ===
;大きな整数:<syntaxhighlight lang=Crystal>
p 2 ** 999
p (2 ** 999).class
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
Integer
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
Unhandled exception: Arithmetic overflow (OverflowError)
from /usr/local/share/crystal/share/crystal/src/int.cr:295:9 in '**'
from pow.cr:1:1 in '__crystal_main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:101:7 in 'main'
from /usr/local/share/crystal/share/crystal/src/crystal/main.cr:127:3 in 'main'
from /usr/local/lib64/libc.so.6 in '__libc_start_main'
from /usr/local/.cache/crystal/crystal-run-pow.tmp in '_start'
from ???
</syntaxhighlight>
: Ruby の整数は、桁あふれが起こると自動的に多倍長整数に型変換されるので、継ぎ目なしに大きな数を扱うアルゴルズムが使えます。
: Crystal の整数は、固定長です(大きさについては[[#リテラルと型|後述]])。なので大きな答えになる式を評価すると桁あふれが生じます。桁あふれが生じますが、C言語のように寡黙に処理を続けるのではなく、実行時に例外(OverflowError)が上がるので、例外を捕捉し然るべき処置を施すことが可能です。
==== BigInt ====
<code>big</code> を <code>require</code> すると <code>BigInt</code> が使えるようになります。
;BigInt:<syntaxhighlight lang=Crystal>
require "big"
p BigInt.new(2) ** 999
p (BigInt.new(2) ** 999).class
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="console">
5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688
BigInt
</syntaxhighlight>
: BigIntはプリミティブではなので、リテラル表現はありません。また、
::<syntaxhighlight lang=Crystal>
n : BigInt = 2
</syntaxhighlight>
::<syntaxhighlight lang=console>
Error: type must be BigInt, not Int32
</syntaxhighlight>
:: のように型アノテーションすることも出来ません。
=== リテラルと型 ===
;様々なリテラルと型:<syntaxhighlight lang=Crystal>
[nil, false, true, 42, 2.73, 'Q', "string", [1,2,3], {a:1, b:2}].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;rubyの実行結果:<syntaxhighlight lang="console">
[nil, NilClass]
[false, FalseClass]
[true, TrueClass]
[42, Integer]
[2.73, Float]
["Q", String]
["string", String]
[[1, 2, 3], Array]
[{:a=>1, :b=>2}, Hash]
</syntaxhighlight>
;crystalの実行結果:<syntaxhighlight lang="console">
[nil, Nil]
[false, Bool]
[true, Bool]
[42, Int32]
[2.73, Float64]
['Q', Char]
["string", String]
[[1, 2, 3], Array(Int32)]
[{a: 1, b: 2}, NamedTuple(a: Int32, b: Int32)]
</syntaxhighlight>
: Crystal の整数は Int32、浮動小数点数は Float64 です。
;サイズを指定した数リテラル:<syntaxhighlight lang=Crystal>
[1_i64, 2_u32, 3_u64, 4_i32, 5_i16, 6_u8, 7_i128, 8_u128, 3.14_f32, 1.44_f64].each{|x|
p [x, x.class]
}
</syntaxhighlight>
;ruby:Rubyでは、サーフィックスの付いた数値リテラルは無効
;crystalの実行結果:<syntaxhighlight lang="console">
[1, Int64]
[2, UInt32]
[3, UInt64]
[4, Int32]
[5, Int16]
[6, UInt8]
[7, Int128]
[8, UInt128]
[3.14, Float32]
[1.44, Float64]
</syntaxhighlight>
: Crystal では、数値リテラルに _ で始まるサーフィックスを付け { i:符号付き整数, u:符号なし整数, f:浮動小数点数 } と { 8,16,32,64,128 } のビット幅の組合せです<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/literals/ Literals]</ref>。
=== for式がない ===
Crystal には、Ruby にはある for式がありません。
;Rubyのfor式の構文:<syntaxhighlight lang="ruby">
for 変数 in コレクション
文
end
</syntaxhighlight>
:コレクションは Range, Array, Hash など内部構造を持つオブジェクトです。
:for式は、最後に評価した値を返すので、for'''式'''です。
;for式のeachメソッドによる置換え:<syntaxhighlight lang="ruby">
for x in [ 2, 3, 5, 7, 11 ] do
p x
end
# ↓
[ 2, 3, 5, 7, 11 ].each do | x |
p x
end
</syntaxhighlight>
: の様にコレクションの each メソッドで置換え可能なので、Rubyからの移植でも小規模な書換えで済みます<ref>[https://github.com/crystal-lang/crystal/issues/830 "For" Loop support #830]</ref>(後述のマクロで実装できないかと思いましたが、いまのところ無理のようです)。
また loop 式もありませんが while true; … end で間に合います。Ruby では while 式の条件の次に do が置けますが、Crystal では置けません。
=== eval()がない ===
Crystal には eval() はありません。
Crystalはコンパイル型言語ですので、無理もないことです。
もし、Crystal で eval() を実装しようとすると、Common Lisp の様にインタープリターを丸ごとランタイムに含む必要があります。
これはリーズナブルな選択ではありません。
Crystal では、eval() が必要なケースに(限定的ですが)マクロを使うことで実現出来る可能性があります。
=== マクロ ===
Crystalには、Rubyにはないマクロがあります<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/macros/ Macros - Crystal]</ref>。Rubyは実行時にすべてのオブジェクトにアクセス出来て、メソッド生やし放題なのでマクロは必要ありませんが、Crystalはコンパイル時に型やメソッドを確定する必要があり、特にメソッドジェネレターとしてのマクロにニーズがあります。また、テンプレート言語的なマクロなので、環境変数による条件分岐や、コンテナを渡し繰返し処理する構文もあります(面白いことにマクロには for 文があり、反対にマクロの中では、eachメソッドは使えません)。マクロには <code><nowiki>{{</nowiki>attr.id}}</code> の様にASTへのアクセス手順が用意されており、半ば言語を拡張するようなアプローチを取ることも出来ます。
[TODO:ASTについての解説;コラム向き?]
;マクロを使ったattr_accessorのイミュレーション:<syntaxhighlight lang=crystal>
class Point
def initialize(@x : Int32, @y : Int32)
end
# macro定義
macro attr_accessor(*attrs)
{% for attr in attrs %}
def {{attr.id}}() @{{attr.id}} end
def {{attr.id}}=(var) @{{attr.id}} = var end
{% end %}
end
# macro呼出し
attr_accessor :x, :y
end
pt = Point.new(20, 30)
p [pt.x, pt.y]
t = pt.x
pt.x = pt.y
pt.y = t
p [pt.x, pt.y]
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
[20, 30]
[30, 20]
</syntaxhighlight>
: Ruby には、attr_accessor と言う「クラスのメンバーのアクセサーを自動生成するメソッド」がありますが、Crystalにはないようなので、マクロで実装しました。
:: attr_accessor :name からは
::<syntaxhighlight lang=ruby>
def name() @name end
def name=(val) @name = val end
</syntaxhighlight>相当のコードが生成されます。
[TODO:マクロの機能と構文の説明 *の付いた引数、 <nowiki>{{</nowiki>引数}}、{% … %} 構文]
==== マクロ p! ====
メソッド p は、与えられた「式」の inspaect() の返す値を puts しますが、マクロ p! は、それに先んじて(評価前の)「式」を表示します<ref>[https://crystal-lang.org/api/1.5.0/Crystal/Macros.html#p%21%28%2Aexpressions%29%3ANop-instance-method def p!(*expressions) : Nop]</ref>。
;p!の例:<syntaxhighlight lang=crystal>
x, y = true, false
p! x,y,x && y, x || y, x ^ y, !x, x != y, x == y
ary = [ 1, 2, 3 ]
p! ary
p! ary.map(&. << 1)
p! ary.map(&.to_f)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
x # => true
y # => false
x && y # => false
x || y # => true
x ^ y # => true
!x # => false
x != y # => true
x == y # => false
ary # => [1, 2, 3]
ary.map(&.<<(1)) # => [2, 4, 6]
ary.map(&.to_f) # => [1.0, 2.0, 3.0]
</syntaxhighlight>
===== 入れ子のp! =====
マクロ p! は入れ子に出来ます。また、一旦ASTに変換してから再度ソースコードに変換するので、等価な別の構文に変換されることがあります。
;入れ子のp!:<syntaxhighlight lang=crystal>
p! (
100.times{|i|
p! i
break i if i > 12
}
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
(100.times do |i|
p!(i)
if i > 12
break i
end
end) # => i
# => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
i # => 6
i # => 7
i # => 8
i # => 9
i # => 10
i # => 11
i # => 12
i # => 13
13
</syntaxhighlight>
=== クラス ===
==== シンプルなクラス ====
;シンプルなクラス:<syntaxhighlight lang=crystal highlight="2" line>
class Hello
def initialize(@name : String = "World")
end
def greeting
puts "Hello #{@name}!"
end
end
hello = Hello.new()
hello.greeting
universe = Hello.new("Universe")
universe.greeting
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Hello World!
Hello Universe!
</syntaxhighlight>
:;初期化メソッド
:: <syntaxhighlight lang=crystal line start=4>
def initialize(@name : String = "World")
end
</syntaxhighlight>
::Rubyであれば
:: <syntaxhighlight lang=ruby line start=4>
def initialize(name = "World")
@name = name
end
</syntaxhighlight>
::とするところですが、Crystalでは、型アノテーション <code> : String</code> を使い、引数の型を限定しました。
::また、(@ 付きの)アトリビュート名を仮引数にすると、そのままアトリビュート(a.k.a. インスタンス変数)に仮引数が代入されます。
::これは、C++のコンストラクターのメンバー初期化リストと同じアイディアですが、Crystalではインスタンス変数に @ が前置されるので、仮引数に @ が出現すればインスタンス変数の初期値だと自明で、聡明な選択です。
==== 都市間の大圏距離 ====
[[Ruby#ユーザー定義クラス]]の都市間の大圏距離を求めるメソッドを追加した例を、Crystalに移植しました。
;都市間の大圏距離:<syntaxhighlight lang=crystal highlight=”2,7,12” line>
class GeoCoord
getter :longitude, :latitude
def initialize(@longitude : Float64, @latitude : Float64)
end
def to_s(io)
ew, ns = "東経", "北緯"
long, lat = @longitude, @latitude
ew, long = "西経", -long if long < 0.0
ns, lat = "南緯", -lat if lat < 0.0
io << "(#{ew}: #{long}, #{ns}: #{lat})"
end # https://github.com/crystal-lang/crystal/issues/259
def distance(other)
i, r = Math::PI / 180, 6371.008
Math.acos(Math.sin(@latitude*i) * Math.sin(other.latitude * i) +
Math.cos(@latitude*i) * Math.cos(other.latitude * i) * Math.cos(@longitude * i - other.longitude * i)) * r
end
end
# メソッドの先頭を大文字に出来ないのでクラス名のメソッドは作ることが出来ない
# def GeoCoord(lng : Float64, lat : Float64)
# GeoCoord.new(lng, lat)
# end
Sites = {
"東京駅": GeoCoord.new(139.7673068, 35.6809591),
"シドニー・オペラハウス": GeoCoord.new(151.215278, -33.856778),
"グリニッジ天文台": GeoCoord.new(-0.0014, 51.4778),
}
Sites.each { |name, gc|
puts "#{name}: #{gc}"
}
puts ""
keys, len = Sites.keys, Sites.size
keys.each_with_index { |x, i|
y = keys[(i + 1) % len]
puts "#{x} ⇔ #{y}: #{Sites[x].distance(Sites[y])} [km]"
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
東京駅: (東経: 139.7673068, 北緯: 35.6809591)
シドニー・オペラハウス: (東経: 151.215278, 南緯: 33.856778)
グリニッジ天文台: (西経: 0.0014, 北緯: 51.4778)
東京駅 ⇔ シドニー・オペラハウス: 7823.269299386704 [km]
シドニー・オペラハウス ⇔ グリニッジ天文台: 16987.2708377249 [km]
グリニッジ天文台 ⇔ 東京駅: 9560.546566490015 [km]
</syntaxhighlight>
:Crystal には、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> はありませんが、標準ライブラリーのマクロに <syntaxhighlight lang=crystal inline> getter </syntaxhighlight>があるので
:: <syntaxhighlight lang=crystal line start=2>
getter :longitude, :latitude
</syntaxhighlight>
::としました。
::将来、<syntaxhighlight lang=ruby inline> attr_accessor </syntaxhighlight> が実装される可能性はありますが、姉妹品の<syntaxhighlight lang=crystal inline> setter </syntaxhighlight> との併用が下位互換性を考えると確実です。
: to_s は、Ruby ならば
:: <syntaxhighlight lang=ruby line start=7>
def to_s()
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
"(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
:: ですが、Crystalでは追加の引数 <var>io</var> が必要で
:: <syntaxhighlight lang=ruby line start=7>
def to_s(io)
</syntaxhighlight>
:: <syntaxhighlight lang=ruby line start=12>
io << "(#{ew}: #{long}, #{ns}: #{lat})"
</syntaxhighlight>
: Ruby にはクラス名と同じ名前のメソッドで .new を呼出す文化があるのですが、Crystalはメソッドの先頭を大文字に出来ないので、これは見送りました。
==== 包含と継承 ====
[[JavaScript/クラス#包含と継承]]を、Rubyに移植した[[Ruby#包含と継承]]を、Crystalに移植しました。
;包含と継承の例:<syntaxhighlight lang=crystal line>
class Point
def initialize(@x = 0, @y = 0)
end
def inspect(io)
io << "x:#{@x}, y:#{@y}"
end
def move(dx = 0, dy = 0)
@x, @y = @x + dx, @y + dy
self
end
end
class Shape
def initialize(x = 0, y = 0)
@location = Point.new(x, y)
end
def inspect(io)
@location.inspect(io)
end
def move(x, y)
@location.move(x, y)
self
end
end
class Rectangle < Shape
def initialize(x = 0, y = 0, @width = 0, @height = 0)
super(x, y)
end
def inspect(io)
super(io)
io << ", width:#{@width}, height:#{@height}"
end
end
rct = Rectangle.new(12, 32, 100, 50)
p! rct,
rct.is_a?(Rectangle),
rct.is_a?(Shape),
rct.is_a?(Point),
rct.move(11, 21)
(END)</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
rct # => x:12, y:32, width:100, height:50
rct.is_a?(Rectangle) # => true
rct.is_a?(Shape) # => true
rct.is_a?(Point) # => false
rct.move(11, 21) # => x:23, y:53, width:100, height:50
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy inclusion-and-inheritance.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (16 bytes)
. @location : Point (8 bytes)
|
+- class Rectangle (24 bytes)
@width : Int32 (4 bytes)
@height : Int32 (4 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
===== superclass と subclasses =====
Crystal には、RubyのClassにあるメソッド superclass と subclasses がないので、マクロで実装しました。
;superclass と subclasses:<syntaxhighlight lang=crystal line>
class Class
def self.superclass
{{ @type.superclass }}
end
def self.subclasses : Array(self.class)
{{ @type.subclasses }}.map(&.as(self.class))
end
def self.all_subclasses : Array(self.class)
{% begin %}
[{{ @type.all_subclasses.join(",").id }}] of self.class
{% end %}
end
end
class A end
class AA < A end
class AAA < AA end
class AAB < AA end
class AB < A end
p! A,
A.subclasses,
A.all_subclasses,
AAA.superclass,
A.superclass
c = AAA
while !c.is_a? Nil
p! c.superclass
c = c.superclass
end</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
A # => A
A.subclasses # => [AA, AB]
A.all_subclasses # => [AA, AAA, AAB, AB]
AAA.superclass # => AA
A.superclass # => Reference
c.superclass # => AA
c.superclass # => A
c.superclass # => Reference
c.superclass # => Object
c.superclass # => nil
</syntaxhighlight>
==== 抽象クラス ====
[[Java/抽象クラス]]を、Crystalに移植しました。
;抽象クラスの宣言:<syntaxhighlight lang=Java>
abstract class クラス名
#
end
</syntaxhighlight>
: このクラス名は、 .new でインスタンス化出来ません。
:: Error: can't instantiate abstract class クラス名
: となります。
:インスタンス化することは出来ませんが、抽象クラスを別のクラスが継承する事は出来ます。
:また、抽象クラスを <code>super()</code> を使うことでメソッドを呼び出せるので、抽象メソッドではないメソッド(具象メソッド)を持つことも、インスタンス変数も持つことも出来ます。
:'''抽象クラスの例'''では、Shapeのinitializeメソッドが抽象クラスの具象メソッドとなっています。
;抽象メソッドの宣言:<syntaxhighlight lang=Java>
abstract def メソッド名
</syntaxhighlight>
: 派生先のクラスで、「メソッド名」を定義(def)し忘れると
:: Error: abstract `def クラス名#メソッド名()` must be implemented by クラス名
: となります
;抽象クラスの例:<syntaxhighlight lang=crystal line>
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
abstract class Shape
def initialize(@x = 0.0, @y = 0.0)
end
abstract def to_s(io)
abstract def area
end
class Square < Shape
def initialize(x, y, @wh = 0.0)
super(x, y)
end
def to_s(io)
io << "Square(#{@x}, #{@y}, #{@wh})"
end
def area
@wh * @wh
end
end
class Recrangle < Shape
def initialize(x, y, @w = 0.0, @h = 0.0)
super(x, y)
end
def to_s(io)
io << "Rectanle(#{@x}, #{@y}, #{@w}, #{@h})"
end
def area
@w * @h
end
end
class Circle < Shape
def initialize(x, y, @r = 0.0)
super(x, y)
end
def to_s(io)
io << "Circle(#{@x}, #{@y}, #{@r})"
end
def area
3.1425926536 * @r * @r
end
end
shapes = [
Square.new(5.0, 10.0, 15.0),
Recrangle.new(13.0, 23.0, 20.0, 10.0),
Circle.new(3.0, 2.0, 20.0),
] of Shape
shapes.each do |shape|
puts("#{shape}: #{shape.area}")
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
Square(5.0, 10.0, 15.0): 225.0
Rectanle(13.0, 23.0, 20.0, 10.0): 200.0
Circle(3.0, 2.0, 20.0): 1257.03706144
</syntaxhighlight>
;crystal tool hierarchy:<syntaxhighlight lang=console>
% crystal tool hierarchy abstract.cr -e Shape
- class Object (4 bytes)
|
+- class Reference (4 bytes)
|
+- class Shape (24 bytes)
. @x : Float64 (8 bytes)
. @y : Float64 (8 bytes)
|
+- class Circle (32 bytes)
| @r : Float64 (8 bytes)
|
+- class Recrangle (40 bytes)
| @w : Float64 (8 bytes)
| @h : Float64 (8 bytes)
|
+- class Square (32 bytes)
@wh : Float64 (8 bytes)
</syntaxhighlight>
: crystal の tool hierarchy サブコマンドで、クラスの継承関係がわかります。
: 「包含と継承の例」と比べると、ShapeとRectangleが同じ階層にあることがわかると思います。
[TODO:virtual class::いい例がない]
== キーワード ==
Crystalのキーワード( ''keywords'' ) は、以下の通り。
<code>abstract</code> <code>alias</code> <code>as</code> <code>asm</code> <code>begin</code> <code>break</code> <code>case</code> <code>class</code> <code>def</code> <code>do</code> <code>else</code> <code>elsif</code> <code>end</code> <code>ensure</code> <code>enum</code> <code>extend</code> <code>for</code> <code>fun</code> <code>if</code> <code>include</code> <code>instance_sizeof</code> <code>lib</code> <code>macro</code> <code>module</code> <code>next</code> <code>of</code> <code>out</code> <code>pointerof</code> <code>private</code> <code>protected</code> <code>rescue</code> <code>return</code> <code>require</code> <code>select</code> <code>sizeof</code> <code>struct</code> <code>super</code> <code>then</code> <code>type</code> <code>typeof</code> <code>uninitialized</code> <code>union</code> <code>unless</code> <code>until</code> <code>when</code> <code>while</code> <code>with</code> <code>yield</code>
<!--
<code>__DIR__</code> <code>__END_LINE__</code> <code>__FILE__</code> <code>__LINE__</code>
-->
== 演算子 ==
Crystalは、1つ、2つ、または3つのオペランドを持つ数多くの演算子をサポートしています<ref>[https://crystal-lang.org/reference/1.5/syntax_and_semantics/operators.html Operators]access-date:2022-07-22</ref>。
演算子式は、実際にはメソッド呼び出しとしてパースされます。例えば、<code>a + b</code> は <code>a.+(b)</code> と意味的に同じで、引数 b を持つ a のメソッド + を呼び出すことになります。
{| class="wikitable"
|+ 演算子の優先度
!種類
!演算子
|-
|インデックス アクセサー
|<code>[]</code>, <code>[]?</code>
|-
|単項
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>, <code>!</code>, <code>~</code>
|-
|指数
|<code>**</code>, <code>&**</code>
|-
|乗除
|<code>*</code>, <code>&*</code>, <code>/</code>, <code>//</code>, <code>%</code>
|-
|加減
|<code>+</code>, <code>&+</code>, <code>-</code>, <code>&-</code>
|-
|シフト
|<code><<</code>, <code>>></code>
|-
|ビット間 AND
|<code>&</code>
|-
|ビット間 OR/XOR
|<code><nowiki>|</nowiki></code>,<code>^</code>
|-
|等値
|<code>==</code>, <code>!=</code>, <code>=~</code>, <code>!~</code>, <code>===</code>
|-
|比較
|<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>, <code><=></code>
|-
|論理 AND
|<code>&&</code>
|-
|論理 OR
|<code><nowiki>||</nowiki></code>
|-
|Range
|<code>..</code>, <code>...</code>
|-
|条件
|<code>?:</code>
|-
|代入
|<code>=</code>, <code>[]=</code>, <code>+=</code>, <code>&+=</code>, <code>-=</code>, <code>&-=</code>, <code>*=</code>, <code>&*=</code>, <code>/=</code>, <code>//=</code>, <code>%=</code>, <code><nowiki>|=</nowiki></code>, <code>&=</code>,<code>^=</code>,<code>**=</code>,<code><<=</code>,<code>>>=</code>, <code><nowiki>||=</nowiki></code>, <code>&&=</code>
|-
|スプラット
|<code>*</code>, <code>**</code>
|}
== 制御構造 ==
'''[[w:制御構造|制御構造]]'''(せいぎょこうぞう、''control flow'')とは、「順次」「分岐」「反復」という基本的な処理のことを言います。
{{コラム|Crystalの真理値|2=
制御構造は「条件式」が真であるか偽であるかによって分岐や反復の振る舞いが変わります。
では「条件式」が真・偽はどの様に決まるのでしょう?
Crystalでは <code>false</code> あるいは <code>nil</code> であると偽、それ以外が真です。
なので <code>0</code> も <code>[]</code>(空のArray) も <code>{}</code>(空のNamedTuple)も真です。
}}
=== 条件分岐 ===
Crystalの条件分岐には、[[#if|if]], [[#until|until]] と [[#case|case]]の3つの構文があります。
==== if ====
'''[[w:if|if]]'''は条件式によって実行・否を切り替える構造構文で、評価した式の値を返すので条件演算子でもあります。
;ifの例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
if a < 0
puts "minus"
elsif a > 0
puts "plus"
elsif a == 0
puts "zero"
else
puts a
end
p! (
if a < 0
"minus"
elsif a > 0
"plus"
elsif a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(if a < 0
"minus"
else
if a > 0
"plus"
else
if a == 0
"zero"
else
a
end
end
end) # => NaN
</syntaxhighlight>
:; elsif節:ifは、オプショナルな elsif 節を設け、条件式が偽であった時に別の条件に合致した処理を実行させることが出来ます。
:; else節:ifは、オプショナルな else 節を設け、条件式が偽であった時に処理を実行させることが出来ます。
: ifは値を返すので、メソッドの実引数に使うことが出来ますし、代入演算の右辺にも使えます。
==== 後置のif ====
Crystalには、RubyやPerlのような後置のifがあります。
;後置のifの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" if n == 0
puts "nは1" if n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは0
</syntaxhighlight>
==== unless====
'''unless'''(アンレス)は条件式によって実行・否を切り替える構造構文ですが、ifとは条件式に対する挙動が逆です。
;unless文の例:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
unless a == 0
puts "Non-zero"
else
puts a
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Non-zero
</syntaxhighlight>
:; else節 : unless文は、オプショナルな else 節を設け、条件式が真であった時に処理を実行させることが出来ます。
::また、unless文は elsif 節は持てません。
==== 後置のunless ====
Crystalには、RubyやPerlのような後置のunlessがあります。
;後置のunlessの例:<syntaxhighlight lang=crystal>
n = 0
puts "nは0" unless n == 0
puts "nは1" unless n == 1
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
nは1ではない
</syntaxhighlight>
==== case ====
caseは、複数の条件式によって処理を降る分ける用途の為に用意されています。
;caseの例:<syntaxhighlight lang=crystal line>
n = 2
case n
when 1
puts "one"
when 2
puts "two"
when 3
puts "three"
else
puts "other"
end
p! (
case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
two
(case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end) # => "two"</syntaxhighlight>
:C言語系のswitch文に慣れた人はbreakがないことに気がつくと思います。Crystalのcaseはfall throughしませんし、fall throughさせる方法もありません。
===== when節が定数でなく式を受付けます =====
[[#if|if]]を使ったコードをcaseに書き換えてみましょう。
;case の式の省略:<syntaxhighlight lang=crystal line>
a = 0.0 / 0.0
case
when a < 0
puts "minus"
when a > 0
puts "plus"
when a == 0
puts "zero"
else
puts a
end
p! (
case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NaN
(case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end) # => NaN
</syntaxhighlight>
このコードは when 節の式の値とcaseの式を <code>===</code> で比較し、最初に一致した when に対応する式が実行される事を利用しています。
===== 型による分岐 =====
when 節が式ではなく型であった場合、caseの式を <code>is_a?</code> で評価し、最初に一致した when に対応する式が実行されます。
;型による分岐:<syntaxhighlight lang=crystal line>
p! 0.class,
0.is_a?(Object),
0.is_a?(Int32),
0.is_a?(Number),
0.is_a?(String)
case 0
when String
puts "String"
when Number
puts "Number"
when Int32
puts "Int32"
when Object
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0.class # => Int32
0.is_a?(Object) # => true
0.is_a?(Int32) # => true
0.is_a?(Number) # => true
0.is_a?(String) # => false
Number
</syntaxhighlight>
暗黙のオブジェクト構文を使うと
:<syntaxhighlight lang=crystal line>
case 0
when .is_a?(String)
puts "String"
when .is_a?(Number)
puts "Number"
when .is_a(Int32)
puts "Int32"
when .is_a(Object)
puts "Object"
else
puts "Unknown"
end
</syntaxhighlight>
:と書くことが出来ます。
:: メソッドは、.is_a? に限定しないので、 .odd? .even? .include? など Bool を返すメソッドなら何でも使えます。
when に対応する式は、1つのことが珍しくないので、その場合は省略可能な then を補うと、1行で書けます。
:<syntaxhighlight lang=crystal line>
case 0
when String then puts "String"
when Number then puts "Number"
when Int32 then puts "Int32"
when Object then puts "Object"
else puts "Unknown"
end
</syntaxhighlight>
[TODO:タプルとダミー識別子 _ ]
===== 網羅性の検査 =====
when の代わりに in を使用すると、exhaustive case 式が作成されます。exhaustive case では、必要な in 条件を省略するとコンパイル時にエラーとなります。exhaustive case 式では、when 節と else 節を含むことはできません。
;Enumの網羅性チェック(網羅不完全):<syntaxhighlight lang=crystal line highlight=11>
enum Colours
Red
Green
Blue
end
colour : Colours = Colours::Red
q = case colour
in Colours::Red then "赤"
in .green? then "緑"
# in .blue? then "青"
end
p q
</syntaxhighlight>
;コンパイルエラー:<syntaxhighlight lang="text">
Showing last frame. Use --error-trace for full trace.
In enumcase.cr:8:5
8 | q = case colour
^
Error: case is not exhaustive for enum Colours.
Missing members:
- Blue
</syntaxhighlight>
: case - in 式の in が列挙型の要素を網羅していないと、コンパイル時にこの様にエラーになります。
:: Colours::Red と .red? は同義です(enum では、要素名を小文字にし最後に ? が付いたメソッドが生えてきます)。
;Enumの網羅性チェック(網羅完全):<syntaxhighlight lang=crystal line highlight=11>
enum Colours
Red
Green
Blue
end
colour : Colours = Colours::Red
q = case colour
in Colours::Red then "赤"
in .green? then "緑"
in .blue? then "青"
end
p q
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
"赤"
</syntaxhighlight>
[TODO:短絡評価 && || ]
=== 繰返し ===
Crystalには、他のプログラミング言語のような[[#繰返し構文|繰返し構文]]と、[[#イテレーターメソッド|イテレーターメソッド]]があります。
==== 繰返し構文 ====
Crystalの繰返し構文には、while と untilの2つがあります<ref>for も do-while も loop もありません。</ref>。
===== while =====
while(ホワイル)は条件が'''真'''である間、式を実行しつづけます。
;構文:<syntaxhighlight lang=crystal>
while 条件式
式1
式2
:
式n
end
</syntaxhighlight>
: Rubyと違い、条件式の後ろに <code>do</code> をつけることは出来ません。
;while文のコード例:<syntaxhighlight lang=crystal line>
i = 0
p! (
while i < 10
p! i
i += 1
break i if i > 5
end
)
</syntaxhighlight>
: 2行目の <code>i < 5</code>が真の間、次の2行を繰返します。
: 4行目の <code>i += 1</code> は <code>i = i + 1</code> の構文糖
;実行結果:<syntaxhighlight lang="text">
(while i < 10
p!(i)
i = i + 1
if i > 5
break i
end
end)# =>
i # => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
6
</syntaxhighlight>
===== until =====
until(アンティル)は条件が'''偽'''である間、式を実行しつづけます。whileとは条件に対する挙動が逆です。
;構文:<syntaxhighlight lang=crystal>
until 条件式 [ do ]
文1
文2
:
文n
end
</syntaxhighlight>
: <code>do</code> は省略できます。
;untilのコード例:<syntaxhighlight lang=crystal line>
i = 0
until i == 3
puts i
i += 1
end
</syntaxhighlight>
: 2行目の <code>i == 3</code>が偽の間、次の2行を繰返します。
;実行結果:<syntaxhighlight lang="text">
0
1
2
</syntaxhighlight>
===== for =====
Crystalにはforがありませんが、コレクションのイテレーションメソッドを使うことで繰返しを簡素に実現出来ます。
==== Rangeオブジェクト ====
Rangeオブジェクトは、整数の区間を表し範囲演算子 <code>開始 ... 終了</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
rng = 1..3
puts rng.class
rng.each do | n |
puts "#{n}番";
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Range(Int32, Int32)
1番
2番
3番
</syntaxhighlight>
==== Arrayオブジェクト ====
Arrayオブジェクトは、任意の Crystal オブジェクトを要素として持つことができます。
配列式<code>[要素1, 要素2, … 要素n]</code> で生成します。
;コード:<syntaxhighlight lang=crystal>
animals = ["ネコ", "金魚", "ハムスター"]
puts animals.class
animals.each do | animal |
puts "動物 #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Array(String)
動物 ネコ
動物 金魚
動物 ハムスター
</syntaxhighlight>
==== NamedTupleオブジェクト ====
NamedTupleオブジェクトは、任意の Crystal オブジェクトをキーに、任意の Crystal オブジェクトを値に持つことができる連想配列です。
NamedTuple式<code>{キー1 => 値1, キー2 => 値2, キーn => 値n}</code> で生成します。
また、キーが Symbol の場合
NamedTuple式<code>{キー1: 値1, キー2: 値2, キーn: 値n}</code> で生成することが出来ます。
;コード:<syntaxhighlight lang=crystal>
animals = {cat: "ネコ", gold_fish: "金魚", hamster: "ハムスター"}
puts animals.class
animals.each do | en, animal |
puts "動物 #{en}: #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NamedTuple(cat: String, gold_fish: String, hamster: String)
動物 cat: ネコ
動物 gold_fish: 金魚
動物 hamster: ハムスター
</syntaxhighlight>
このように、Crystalではforがなくてもコレクションのメソッドで同様の処理を実現できます。
===== loop =====
loop、ありません。
while true で代用します。
;loopの代用コード例:<syntaxhighlight lang=crystal line>
i = 1
while true
puts "0b%b" % i
i <<= 1
break if i > 2**8
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0b1
0b10
0b100
0b1000
0b10000
0b100000
0b1000000
0b10000000
0b100000000
</syntaxhighlight>
:5行目の、<code>break if i > 2**8</code>でループを脱出するようにしています。この様に break や return あるいは例外が上がらないとループは永久に終わりません。
:このコードは、Crystalにはない do-while文を模倣する例にもなっています。
==== イテレーターメソッド ====
===== Integer#times =====
Integer#timesは与えられたブロックをオブジェクトの示す整数値回くりかえします。
:コード<syntaxhighlight lang=crystal>
3.times{ puts "Hello, world!" }
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Hello, world!
Hello, world!
Hello, world!
</syntaxhighlight>
;ループ変数を使た例:<syntaxhighlight lang=crystal>
3.times do |i|
puts "#{i}の倍は#{2 * i}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
0の倍は0
1の倍は2
2の倍は4
</syntaxhighlight>
;ブロックを伴わないtimesメソッド:<syntaxhighlight lang=crystal>
iter = 3.times
puts iter.class
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
p! iter.next
# puts iter.next # `next': StopIteration: iteration reached an end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Int::TimesIterator(Int32)
iter.next # => 0
iter.next # => 1
iter.next # => 2
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
iter.next # => #<Iterator::Stop:0x7fb5bedd7fe0>
</syntaxhighlight>
: Integer#times にブロックを渡さないと、Int::TimesIterator([T])オブジェクトが返ります。
: Int::TimesIterator([T])オブジェクトは外部イテレーターと呼ばれnextメソッドで反復を行えます。
== メソッド ==
=== クラスのメソッド一覧 ===
Crystal には、Objectクラスにmethodsメソッドがないので、マクロで実装しました。
;RubyのObject#methods:<syntaxhighlight lang=ruby>
p Object.methods.sort,
Integer.methods.sort,
Float.methods.sort,
Array.methods.sort,
Range.methods.sort
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :sqrt, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :[], :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :try_convert, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :alias_method, :allocate, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :const_source_location, :constants, :define_method, :define_singleton_method, :deprecate_constant, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include, :include?, :included_modules, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :remove_instance_variable, :remove_method, :respond_to?, :send, :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :subclasses, :superclass, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :undef_method, :untaint, :untrust, :untrusted?, :yield_self]
</syntaxhighlight>
;Crystalに実装したmethodsマクロ:<syntaxhighlight lang=crystal>
class Object
macro methods
{{ @type.methods.map(&.name.stringify).sort.uniq }}
end
end
p! Object.methods,
Reference.methods,
Array.methods,
Box.methods,
Channel.methods,
Deque.methods,
Dir.methods,
Exception.methods,
ArgumentError.methods,
DivisionByZeroError.methods,
IndexError.methods,
InvalidByteSequenceError.methods,
Fiber.methods,
Hash.methods,
IO.methods,
File.methods,
Mutex.methods,
PrettyPrint.methods,
Process.methods,
Regex.methods,
String.methods,
Thread.methods,
Bool.methods,
Int32.methods,
Float64.methods,
Proc.methods
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text" style="overflow: scroll;height:7em">
Object.methods # => ["!=", "!~", "==", "===", "=~", "class", "crystal_type_id", "dup", "hash", "in?", "inspect", "itself", "not_nil!", "pretty_inspect", "pretty_print", "tap", "to_s", "try", "unsafe_as"]
Reference.methods # => ["==", "dup", "exec_recursive", "exec_recursive_clone", "hash", "inspect", "object_id", "pretty_print", "same?", "to_s"]
Array.methods # => ["&", "*", "+", "-", "<<", "<=>", "==", "[]", "[]=", "[]?", "calculate_new_capacity", "check_needs_resize", "check_needs_resize_for_unshift", "clear", "clone", "compact", "compact!", "concat", "delete", "delete_at", "dup", "each_repeated_permutation", "fill", "first", "flatten", "increase_capacity", "increase_capacity_for_unshift", "index", "initialize", "insert", "inspect", "internal_delete", "last", "map", "map_with_index", "needs_resize?", "pop", "pop?", "pretty_print", "product", "push", "reject!", "remaining_capacity", "repeated_permutations", "replace", "reset_buffer_to_root_buffer", "resize_if_cant_insert", "resize_to_capacity", "resize_to_capacity_for_unshift", "reverse", "root_buffer", "rotate", "rotate!", "select!", "shift", "shift?", "shift_buffer_by", "shift_when_not_empty", "shuffle", "size", "size=", "skip", "sort", "sort!", "sort_by", "sort_by!", "to_a", "to_lookup_hash", "to_s", "to_unsafe", "to_unsafe_slice", "transpose", "truncate", "uniq", "uniq!", "unsafe_fetch", "unsafe_put", "unshift", "unstable_sort", "unstable_sort!", "unstable_sort_by", "unstable_sort_by!", "|"]
Box.methods # => ["initialize", "object"]
Channel.methods # => ["close", "closed?", "dequeue_receiver", "dequeue_sender", "initialize", "inspect", "pretty_print", "receive", "receive?", "receive_impl", "receive_internal", "receive_select_action", "receive_select_action?", "send", "send_internal", "send_select_action"]
Deque.methods # => ["+", "<<", "==", "buffer", "clear", "clone", "concat", "delete", "delete_at", "dup", "each", "halfs", "increase_capacity", "initialize", "insert", "inspect", "internal_delete", "pop", "pop?", "pretty_print", "push", "reject!", "rotate!", "select!", "shift", "shift?", "size", "size=", "to_s", "unsafe_fetch", "unsafe_put", "unshift"]
Dir.methods # => ["children", "close", "each", "each_child", "entries", "initialize", "inspect", "path", "pretty_print", "read", "rewind", "to_s"]
Exception.methods # => ["backtrace", "backtrace?", "callstack", "callstack=", "cause", "initialize", "inspect", "inspect_with_backtrace", "message", "to_s"]
ArgumentError.methods # => ["initialize"]
DivisionByZeroError.methods # => ["initialize"]
IndexError.methods # => ["initialize"]
InvalidByteSequenceError.methods # => ["initialize"]
Fiber.methods # => ["cancel_timeout", "dead?", "enqueue", "initialize", "inspect", "makecontext", "name", "name=", "next", "next=", "previous", "previous=", "push_gc_roots", "resumable?", "resume", "resume_event", "run", "running?", "stack_bottom", "stack_bottom=", "timeout", "timeout_event", "timeout_select_action", "timeout_select_action=", "to_s"]
Hash.methods # => ["==", "[]", "[]=", "[]?", "add_entry_and_increment_size", "clear", "clear_entries", "clear_impl", "clear_indices", "clone", "compact", "compact!", "compare_by_identity", "compare_by_identity?", "compute_indices_bytesize", "delete", "delete_entry", "delete_entry_and_update_counts", "delete_impl", "delete_linear_scan", "dig", "dig?", "do_compaction", "double_indices_size", "dup", "each", "each_entry_with_index", "each_key", "each_value", "empty?", "entries", "entries_capacity", "entries_full?", "entries_size", "entry_matches?", "fetch", "find_entry", "find_entry_with_index", "find_entry_with_index_linear_scan", "first_entry?", "first_key", "first_key?", "first_value", "first_value?", "fit_in_indices", "get_entry", "get_index", "has_key?", "has_value?", "hash", "indices_malloc_size", "indices_size", "initialize", "initialize_clone", "initialize_clone_entries", "initialize_compare_by_identity", "initialize_copy_non_entries_vars", "initialize_default_block", "initialize_dup", "initialize_dup_entries", "inspect", "invert", "key_for", "key_for?", "key_hash", "keys", "last_entry?", "last_key", "last_key?", "last_value", "last_value?", "malloc_entries", "malloc_indices", "merge", "merge!", "merge_into!", "next_index", "pretty_print", "proper_subset_of?", "proper_superset_of?", "put", "realloc_entries", "realloc_indices", "rehash", "reject", "reject!", "resize", "select", "select!", "set_entry", "set_index", "shift", "shift?", "size", "subset_of?", "superset_of?", "to_a", "to_a_impl", "to_h", "to_s", "transform_keys", "transform_values", "transform_values!", "update", "update_linear_scan", "upsert", "values", "values_at"]
IO.methods # => ["<<", "check_open", "close", "closed?", "decoder", "each_byte", "each_char", "each_line", "encoder", "encoding", "flush", "getb_to_end", "gets", "gets_peek", "gets_slow", "gets_to_end", "has_non_utf8_encoding?", "peek", "peek_or_read_utf8", "peek_or_read_utf8_masked", "pos", "pos=", "print", "printf", "puts", "read", "read_at", "read_byte", "read_bytes", "read_char", "read_char_with_bytesize", "read_fully", "read_fully?", "read_line", "read_string", "read_utf8", "read_utf8_byte", "rewind", "seek", "set_encoding", "skip", "skip_to_end", "tell", "tty?", "utf8_encoding?", "write", "write_byte", "write_bytes", "write_string", "write_utf8"]
File.methods # => ["delete", "initialize", "inspect", "path", "read_at", "size", "truncate"]
Mutex.methods # => ["initialize", "lock", "lock_slow", "synchronize", "try_lock", "unlock"]
PrettyPrint.methods # => ["break_outmost_groups", "breakable", "comma", "current_group", "fill_breakable", "flush", "group", "group_queue", "group_sub", "indent", "initialize", "list", "nest", "newline", "surround", "text"]
Process.methods # => ["channel", "close", "close_io", "copy_io", "ensure_channel", "error", "error?", "exists?", "finalize", "initialize", "input", "input?", "output", "output?", "pid", "signal", "stdio_to_fd", "terminate", "terminated?", "wait"]
Regex.methods # => ["+", "==", "===", "=~", "capture_count", "clone", "dup", "finalize", "hash", "initialize", "inspect", "internal_matches?", "match", "match_at_byte_index", "matches?", "matches_at_byte_index?", "name_table", "options", "source", "to_s"]
String.methods # => ["%", "*", "+", "<=>", "==", "=~", "[]", "[]?", "ascii_only?", "blank?", "byte_at", "byte_at?", "byte_delete_at", "byte_index", "byte_index_to_char_index", "byte_slice", "byte_slice?", "bytes", "bytesize", "calc_excess_left", "calc_excess_right", "camelcase", "capitalize", "center", "char_at", "char_bytesize_at", "char_index_to_byte_index", "chars", "check_no_null_byte", "chomp", "clone", "codepoint_at", "codepoints", "compare", "count", "delete", "delete_at", "downcase", "dump", "dump_char", "dump_hex", "dump_or_inspect", "dump_or_inspect_char", "dump_or_inspect_unquoted", "dump_unquoted", "dup", "each_byte", "each_byte_index_and_char_index", "each_char", "each_char_with_index", "each_codepoint", "each_grapheme", "each_grapheme_boundary", "each_line", "empty?", "encode", "ends_with?", "find_start_and_end", "grapheme_size", "graphemes", "gsub", "gsub_append", "gsub_ascii_char", "has_back_references?", "hash", "hexbytes", "hexbytes?", "includes?", "index", "insert", "insert_impl", "inspect", "inspect_char", "inspect_unquoted", "just", "lchop", "lchop?", "lines", "ljust", "lstrip", "match", "matches?", "partition", "presence", "pretty_print", "rchop", "rchop?", "remove_excess", "remove_excess_left", "remove_excess_right", "reverse", "rindex", "rjust", "rpartition", "rstrip", "scan", "scan_backreferences", "scrub", "single_byte_optimizable?", "size", "size_known?", "split", "split_by_empty_separator", "split_single_byte", "squeeze", "starts_with?", "strip", "sub", "sub_append", "sub_index", "sub_range", "succ", "titleize", "to_f", "to_f32", "to_f32?", "to_f64", "to_f64?", "to_f?", "to_f_impl", "to_i", "to_i128", "to_i128?", "to_i16", "to_i16?", "to_i32", "to_i32?", "to_i64", "to_i64?", "to_i8", "to_i8?", "to_i?", "to_s", "to_slice", "to_u128", "to_u128?", "to_u16", "to_u16?", "to_u32", "to_u32?", "to_u64", "to_u64?", "to_u8", "to_u8?", "to_unsafe", "to_unsigned_info", "to_utf16", "tr", "underscore", "unicode_delete_at", "unsafe_byte_at", "unsafe_byte_slice", "unsafe_byte_slice_string", "upcase", "valid_encoding?"]
Thread.methods # => ["detach", "event_base", "gc_thread_handler", "gc_thread_handler=", "initialize", "join", "main_fiber", "next", "next=", "previous", "previous=", "scheduler", "stack_address", "start", "to_unsafe"]
Bool.methods # => ["!=", "&", "==", "^", "clone", "hash", "to_s", "to_unsafe", "|"]
Int32.methods # => ["!=", "&", "&*", "&+", "&-", "*", "+", "-", "/", "<", "<=", "==", ">", ">=", "^", "clone", "leading_zeros_count", "popcount", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trailing_zeros_count", "unsafe_chr", "unsafe_div", "unsafe_mod", "unsafe_shl", "unsafe_shr", "|"]
Float64.methods # => ["!=", "*", "**", "+", "-", "/", "<", "<=", "==", ">", ">=", "ceil", "clone", "fdiv", "floor", "next_float", "prev_float", "round_away", "round_even", "to_f", "to_f!", "to_f32", "to_f32!", "to_f64", "to_f64!", "to_i", "to_i!", "to_i128", "to_i128!", "to_i16", "to_i16!", "to_i32", "to_i32!", "to_i64", "to_i64!", "to_i8", "to_i8!", "to_s", "to_u", "to_u!", "to_u128", "to_u128!", "to_u16", "to_u16!", "to_u32", "to_u32!", "to_u64", "to_u64!", "to_u8", "to_u8!", "trunc"]
Proc.methods # => ["==", "===", "arity", "call", "clone", "closure?", "closure_data", "hash", "internal_representation", "partial", "pointer", "to_s"]</syntaxhighlight>
== 脚註 ==
<references />
== 外部リンク ==
* [https://crystal-lang.org/ The Crystal Programming Language] {{---}} 公式サイト
** [https://crystal-lang.org/reference/1.5/ ドキュメント]
*** [https://crystal-lang.org/api/1.5.0/ APIマニュアル]
** [https://play.crystal-lang.org/#/cr Compile & run code in Crystal] {{---}} playground
[[Category:Crystal|*]]
[[Category:プログラミング言語]]
{{NDC|007.64}}
0lr809tzbba7g0p5i7797mmcg9qvryj
Wikibooks:GUS2Wiki
4
35248
205826
205743
2022-07-25T07:22:23Z
Alexis Jazz
56315
Updating gadget usage statistics from [[Special:GadgetUsage]] ([[phab:T121049]])
wikitext
text/x-wiki
{{#ifexist:Project:GUS2Wiki/top|{{/top}}|This page provides a historical record of [[Special:GadgetUsage]] through its page history. To get the data in CSV format, see wikitext. To customize this message or add categories, create [[/top]].}}
以下のデータは 2022-07-23T09:12:57Z に最終更新されたキャッシュです。
{| class="sortable wikitable"
! ガジェット !! data-sort-type="number" | 利用者の数 !! data-sort-type="number" | 活動中の利用者
|-
|Blackskin || 7 || 0
|-
|Navigation popups || 79 || 2
|-
|UTCLiveClock || 43 || 0
|-
|edittop || 52 || 0
|-
|exlinks || 45 || 0
|-
|removeAccessKeys || 7 || 0
|-
|wikEd || 42 || 1
|}
* [[特別:GadgetUsage]]
* [[w:en:Wikipedia:GUS2Wiki/Script|GUS2Wiki]]
<!-- data in CSV format:
Blackskin,7,0
Navigation popups,79,2
UTCLiveClock,43,0
edittop,52,0
exlinks,45,0
removeAccessKeys,7,0
wikEd,42,1
-->
fhbeviyoxzxfg0jfqf28payrvydxlxa
トーク:Zig
1
35256
205827
2022-07-25T07:25:46Z
すじにくシチュー
12058
/* 要約欄でウソをつくの、やめようね */ 新しい節
wikitext
text/x-wiki
== 要約欄でウソをつくの、やめようね ==
とりあえず、要約欄でウソをつくの、迷惑なんで、やめてください。
[https://ja.wikibooks.org/w/index.php?title=Zig&diff=205774&oldid=205772 2022年7月24日 (日) 07:31時点における版 (編集) (取り消し) (感謝)
Ef3 (トーク | 投稿記録)(すじにくシチュー (トーク) による版 205772 を取り消し。前の行と重複。)]
とあって、まあ、中段の
<pre>「のように、<code>{c}</code>なら対応する文字の引用符はシングルクォーテーション<code>' '</code>に、<code>{s}</code>なら対応する文字'''列'''の引用符はダブルクォーテーション<code>" "</code>でなければなりません。
<.pre>
の部分は重複気味ってのは分かるんですが、
しかし「文字型の場合は {c} と文字であることを明記すると文字表現となります。」に続く
<pre>
また、引用符の側も、シングルクォーテーションにすることで、厳密に文字型であることを区別しています(Fedora36で実行して確認)。
</pre>
は直前の文章とは特になんの重複もしていません。
{c} を「シングルクオーテーション」とは言いません。過去にも Ef3 さんは要約欄でたびたび、ウソをついています。せっかくプログラミング知識があるのにウソツキなせいで、少なくとも私からの信用は低いです。多少プログラミング知識が欠けてもウソをつかない人と共同作業をしたいものです。
どうやら Ef3 さんには、ウソをついて、自分好みのスタイルではない編集を除去する悪癖があるように見えます。相手の編集に不備があると思うなら、ウソをつかずに堂々とだと不備を指摘して上書きすればいいだけです。--[[利用者:すじにくシチュー|すじにくシチュー]] ([[利用者・トーク:すじにくシチュー|トーク]]) 2022年7月25日 (月) 07:25 (UTC)
o6ga1lffhl24b6hyi8pofmtf6ljp781
205829
205827
2022-07-25T07:26:46Z
すじにくシチュー
12058
typo
wikitext
text/x-wiki
== 要約欄でウソをつくの、やめようね ==
とりあえず、要約欄でウソをつくの、迷惑なんで、やめてください。
[https://ja.wikibooks.org/w/index.php?title=Zig&diff=205774&oldid=205772 2022年7月24日 (日) 07:31時点における版 (編集) (取り消し) (感謝)
Ef3 (トーク | 投稿記録)(すじにくシチュー (トーク) による版 205772 を取り消し。前の行と重複。)]
とあって、まあ、中段の
<pre>「のように、<code>{c}</code>なら対応する文字の引用符はシングルクォーテーション<code>' '</code>に、<code>{s}</code>なら対応する文字'''列'''の引用符はダブルクォーテーション<code>" "</code>でなければなりません。
</pre>
の部分は重複気味ってのは分かるんですが、
しかし「文字型の場合は {c} と文字であることを明記すると文字表現となります。」に続く
<pre>
また、引用符の側も、シングルクォーテーションにすることで、厳密に文字型であることを区別しています(Fedora36で実行して確認)。
</pre>
は直前の文章とは特になんの重複もしていません。
{c} を「シングルクオーテーション」とは言いません。過去にも Ef3 さんは要約欄でたびたび、ウソをついています。せっかくプログラミング知識があるのにウソツキなせいで、少なくとも私からの信用は低いです。多少プログラミング知識が欠けてもウソをつかない人と共同作業をしたいものです。
どうやら Ef3 さんには、ウソをついて、自分好みのスタイルではない編集を除去する悪癖があるように見えます。相手の編集に不備があると思うなら、ウソをつかずに堂々とだと不備を指摘して上書きすればいいだけです。--[[利用者:すじにくシチュー|すじにくシチュー]] ([[利用者・トーク:すじにくシチュー|トーク]]) 2022年7月25日 (月) 07:26 (UTC)
qfp4c479bazn2235jg4qey4v65gjctt