Home

Dev Power ~開発の力~

なんで燃えるのか

ソフトウェア開発をしていると、燃えるという現場に遭遇することがあります。
この業界では消えることがありません。いえ、消えてもどこかで火の手が上がります。
まぁ、自分が火種になることもあるのですが。。。

燃えているという状態は、納期間近や納期オーバーしているのに全然
終わる見込みが見えない混沌とした状態かと思います。

なぜそんな状態になるのかというと、代表的なところだと
 ・仕様の理解不測で少ない工数を見積もっていたのが理解が深まると同時に工数が増える
 ・仕様の未決定を放置し、後半に仕様が決定して工数が増える
 ・進捗が進んでないメンバーの状況を把握できずに蓋を開けるとドッカン
 ・出来ていると思っていたら不具合だらけ
なんてところでしょうか。

簡単に言うと自分(自分たち)が何を何処までする必要があるのかと、
何処まで進んでいるのかを正確に把握できていないことが原因だと思います。

自分の作業、メンバーがいる方はメンバーの作業に関して、何を何処まで
する必要があるのか把握できていますか?

このエントリーをはてなブックマークに追加
はてなブックマーク - なんで燃えるのか
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

情報処理技術者試験

会社の資格手当てに目が眩んで情報処理技術者試験の
エンベデッドシステムスペシャリスト試験を受けたのです。
今年は震災の影響で通年より遅れて特別試験という
形での試験でした。

本日、結果発表がありまして、合格していました。
(恥ずかしくて点数は言えないですけど。。。)
今回2回目で、1回目は午前Ⅱの時点で不合格でした。

通常、開発業務をしている人にとって午後の試験は
どうにかなるのですが、午前の試験はそれなりに試験勉強と
いうものをしないとダメでした。
故障率なんて仕事で使ったことないし。。。

ググれば、ほとんどの知識は取得できる時代に、記憶力を
問う試験はいかがなものでしょうね。
まぁ、開発現場で情報漏洩防止のためネットに繋がっていない
ところもありますけど。
ちなみに、午後の試験は記憶力は全然問われなくて、純粋に開発の
思考力を問われます。

このエントリーをはてなブックマークに追加
はてなブックマーク - 情報処理技術者試験
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

Xcode4.1

Xcode4.1にバージョンアップしました。
いつの間にか、Xcode4.1が無料公開されていました。
あの有料だったのはなんだったんだろう?
と思いきや、OSがVersion10.7でないとインストールできませんでした。
つまりLionでないとインストールできないのです。
ということで、MacのOSをLionにバージョンアップして、Xcode4.1を
インストールしたのです。
Lionにバージョンアップするのに2600円かかるので無料になったの
ですかね。

このエントリーをはてなブックマークに追加
はてなブックマーク - Xcode4.1
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

リバーシを作る その6 メッセージ

リバーシを作るの6回目です。

いよいよ最終回です。
終了判定、メッセージ表示、パス処理を一気に追加します。

まずは、メッセージを表示するLabelとパスのボタンの
Toolbarを置いて接続するので、ReversiViewController.hに
定義します。
ReversiViewController.h

@interface ReversiViewController : UIViewController <ReversiViewDelegate>
{
	ReversiModel *model;
	UILabel* label;
}
 
@property (nonatomic, retain) ReversiModel *model;
@property (nonatomic, retain) IBOutlet UILabel* label;
 
 
- (void) changeLabel:(BoardMessage)message;
- (IBAction)onPassButton:(id)sender;
 
@end


余計なものまで追加されていますが、後で説明しますので
ここでは無視してください。
ここで必要なのは、UILabelの定義とonPassButtonの定義です。

そして、IBで接続します。
ラベルから

次にツールバー


そして、メッセージの処理をコーディングしていきます。
メッセージの定義は、
ReversiModel.h

typedef enum {
	MESSAGE_NON = 0,
	MESSAGE_CAN_NOT_PUT,
	MESSAGE_YOUR_TURN,
	MESSAGE_THINKING,
	MESSAGE_CMP_PASS,
	MESSAGE_YOU_WIN,
	MESSAGE_CMP_WIN,
	MESSAGE_DRAW,
} BoardMessage;


とします。
実際にラベルの文字をセットするのは、
ReversiViewController.m

- (void)changeLabel:(BoardMessage)message
{
	switch (message) {
		case MESSAGE_NON:
			self.label.text = @"";
			break;
		case MESSAGE_CAN_NOT_PUT:
			self.label.text = @"そこには置けません";
			break;
		case MESSAGE_CMP_PASS:
			self.label.text = @"コンピュータはパスです";
			break;
		case MESSAGE_YOU_WIN:
			self.label.text = @"あなたの勝ちです";
			break;
		case MESSAGE_CMP_WIN:
			self.label.text = @"コンピュータの勝ちです";
			break;
		case MESSAGE_DRAW:
			self.label.text = @"引き分けです";
			break;
		case MESSAGE_YOUR_TURN:
			self.label.text = @"あなたの番です";
			break;
	}
}


です。
このchengeLabelはReversiViewから使いたいので、
プロトコルを定義します。
ReversiView.h

@protocol ReversiViewDelegate;
 
@interface ReversiView : UIView {
	UIImage *blackImage;
	UIImage *whiteImage;
	ReversiModel *model;
 
	id <ReversiViewDelegate> delegate;
}
 
@property (retain) UIImage *blackImage;
@property (retain) UIImage *whiteImage;
@property (nonatomic, retain) ReversiModel *model;
@property (assign) id <ReversiViewDelegate> delegate;
 
- (void) drawBoard;
 
@end
 
@protocol ReversiViewDelegate
 
- (void)changeLabel:(BoardMessage)message;
 
@end


そして、先ほど見た、ReversiViewController.hの

@interface ReversiViewController : UIViewController <ReversiViewDelegate>


となります。
Objective-Cでは多重継承できませんが、このデリゲートで
似たようなことができるようになっています。

次に終了処理を追加します。
ReversiModel.m

// 終了チェック
- (BoardMessage)checkEnd
{
	int pieceNum = [self getPieceNum:PIECE_NON];
	if (pieceNum==0) {
		pieceNum = [self getPieceNum:PIECE_BLACK];
		if (pieceNum==32) {
			return MESSAGE_DRAW;
		} else if (pieceNum>32) {
			return MESSAGE_YOU_WIN;
		} else {
			return MESSAGE_CMP_WIN;
		}
	}
	return MESSAGE_NON;
}
 
// 対戦
- (BoardMessage) match:(CGPoint)point
{
	// 置けるかどうかチェックする
	BOOL isCanPut = [self checkCanPutPiece:point:PIECE_BLACK:NO];
 
	if (isCanPut) {
		// 置けるなら黒駒をセットする
		[self checkCanPutPiece:point:PIECE_BLACK:YES];
		[self setBoardPieceInfo:point:PIECE_BLACK];
	} else {
		// 置けないなら何もしない
		return MESSAGE_CAN_NOT_PUT;
	}
 
	BoardMessage msg = [self checkEnd];
	if (msg!=MESSAGE_NON) {
		return msg;
	}
 
	// コンピュータの番
	isCanPut = [self thinkComputer];
	msg = [self checkEnd];
	if (msg!=MESSAGE_NON) {
		return msg;
	}
 
	if (isCanPut) {
		return MESSAGE_YOUR_TURN;
	} else {
		return MESSAGE_CMP_PASS;
	}
 
}



それに伴ってタッチ処理を修正します。
ReversiView.m

-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
	CGPoint touchPoint = [[touches anyObject] locationInView:self];
 
	// タッチした座標からボードの升目の位置を計算する
	CGPoint targetPoint = {0,0};
 
	targetPoint.x = floor(touchPoint.x/40);
	if (targetPoint.x<0) {
		return;
	}
	if (targetPoint.x>7) {
		return;
	}
	targetPoint.y = floor((touchPoint.y-40)/40);
	if (targetPoint.y<0) {
		return;
	}
	if (targetPoint.y>7) {
		return;
	}
 
	BoardMessage msg = [model match:targetPoint];
 
	[delegate changeLabel:msg];
 
	// 描画する
	[self setNeedsDisplay];
}


これで、終了判定とメッセージ表示ができるようになりました。
そして、パスの処理を実装します。

最初に定義した、onPassButtonの実装です。
ReversiViewController.m

- (IBAction)onPassButton:(id)sender
{
	BoardMessage msg = [model Pass];
	[self changeLabel:msg];
	[(ReversiView *)[self view] setNeedsDisplay];
}


実際のパスの処理は、ReversiModelで、
ReversiModel.m

// パス処理
- (BoardMessage) Pass
{
	BOOL isCanPut = [self thinkComputer];
	BoardMessage msg = [self checkEnd];
	if (msg==MESSAGE_NON) {
		if (isCanPut) {
			msg = MESSAGE_YOUR_TURN;
		} else {
			msg = MESSAGE_CMP_PASS;
		}
	}
	return msg;
}


これでコードの修正は終わりです。
では、ビルドして実行してみましょう。


メッセージが出て、終了も判定できるようになりました。
かなり弱いですが、油断すると負けますよ。

さて、6回にわたって作ってきたリバーシも今回で終了です。
AppStoreに出せるようなレベルではありませんが、
一応それなりに動くものができました。
まぁ、なんとかなるものです。

ということで、おしまい。

このエントリーをはてなブックマークに追加
はてなブックマーク - リバーシを作る その6 メッセージ
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

リバーシを作る その5 コンピュータが考える?

リバーシを作るの5回目です。

いよいよ、コンピュータに指手を考えてもらいましょう。
なんて言って、実はとても単純なことしかしません。

優先順位に従って、置けるところを探すだけです。
リバーシは当然、4つの角を先に取りたいので、優先順位は
1〜4番が角になります。それ以降は適当です。。。

本当は、コンピュータの思考ルーチンは、別ソースにするのが
良いのですが、しょぼいコードしかないので、Modelの中に
入れてしまいます。

まずは、優先順位のテーブルです。
ReversiModel.m

// コンピューターの指手を決める優先順位テーブル
static CGPoint thinkArray[60] = {
	{0,0},{7,0},{7,7},{0,7},{2,2},{5,2},{5,5},{2,5},
	{3,9},{4,2},{5,3},{5,4},{4,5},{3,5},{2,4},{2,3},
	{2,1},{2,0},{1,2},{0,2},{5,1},{5,0},{6,2},{7,2},
	{6,5},{7,5},{5,6},{5,7},{2,6},{2,7},{1,5},{0,5},
	{3,0},{4,0},{7,3},{7,4},{4,7},{3,7},{0,4},{0,3},
	{3,1},{4,1},{6,3},{6,4},{4,6},{3,6},{1,4},{1,3},
	{1,1},{6,1},{6,6},{1,6},{1,0},{6,0},{7,1},{7,6},
	{6,7},{1,7},{0,6},{0,1}};


そして、コンピュータの考えるところは

// 優先順位に従い置けるところを探す
- (BOOL) thinkComputer
{
	for (int i=0;i<60;i++) {
		// 置けるかをチェック
		BOOL bResult = [self checkCanPutPiece:thinkArray[i] :PIECE_WHITE :YES];
		if (bResult) {
			// 置けるなら自駒をセット
			[self setBoardPieceInfo:thinkArray[i]:PIECE_WHITE];
			return YES;
		}
	}
	return NO;
}


こんだけです。。。
そして、人が駒を置いた後にコンピュータの思考が走るように
ReversiView.mのtouchesEndedを修正します。

ReversiView.m

	// 置けるかどうかチェックする
	BOOL isCanPut = [model checkCanPutPiece:targetPoint:PIECE_BLACK:NO];
 
	if (isCanPut) {
		// 置けるなら黒駒をセットする
		[model checkCanPutPiece:targetPoint:PIECE_BLACK:YES];
		[model setBoardPieceInfo:targetPoint:PIECE_BLACK];
	} else {
		// 置けないなら何もしない
		return;
	}
 
	[model thinkComputer];
 
	// 描画する
	[self setNeedsDisplay];



これでコードの修正は終わりです。
では、ビルドして実行してみましょう。

人が黒駒で先攻になりますので、対戦してみてください。

まだ終わり判定が無いので中途半端ですが、一応対戦
できるようになりました。

今日は、ここまでです。



このエントリーをはてなブックマークに追加
はてなブックマーク - リバーシを作る その5 コンピュータが考える?
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

Home

最近の投稿
最近のコメント

Return to page top