// テキストファイター
// (C) 2008 アヒルジゲン

// グローバルコンテキスト
var g_context = new Context();

// プレイヤパラメータをセットアップします。
function setupPlayerParameters()
{
    // プレイヤ1用のパラメータ設定
    var normalizedName1 = document.formPlayerName.inputP1Name.value.replace(/\s|　/g, "");
    var hashP1 = calculateHash(normalizedName1);
    var trimmedName1 = document.formPlayerName.inputP1Name.value.replace(/^[\s　]+|[\s　]+$/g, "");
    g_context.player1.name = trimmedName1;
    
    
    g_context.player1.hitPointWeight = parseInt(hashP1[0], 16);
    g_context.player1.attackPointWeight = parseInt(hashP1[1], 16);
    g_context.player1.defencePointWeight = parseInt(hashP1[2], 16);
    g_context.player1.quicknessPointWeight = parseInt(hashP1[3], 16);
    g_context.player1.setupParameters();
    document.getElementById("player1Params").innerHTML = generateParameterMessage(g_context.player1);

    // プレイヤ2用のパラメータ設定
    var normalizedName2 = document.formPlayerName.inputP2Name.value.replace(/\s|　/g, "");
    var hashP2 = calculateHash(normalizedName2);
    var trimmedName2 = document.formPlayerName.inputP2Name.value.replace(/^[\s　]+|[\s　]+$/g, "");
    g_context.player2.name = trimmedName2;
    g_context.player2.hitPointWeight = parseInt(hashP2[0], 16);
    g_context.player2.attackPointWeight = parseInt(hashP2[1], 16);
    g_context.player2.defencePointWeight = parseInt(hashP2[2], 16);
    g_context.player2.quicknessPointWeight = parseInt(hashP2[3], 16);
    g_context.player2.setupParameters();
    document.getElementById("player2Params").innerHTML = generateParameterMessage(g_context.player2);
}

// パラメータを表すメッセージを作成します。
function generateParameterMessage(player)
{
    var message = new String();
    message += "'%s'のパラメータ".sprintf(player.name) + "<br/>";
    message += "<code>";
    message += "体力    :" + "%5.2f".sprintf(player.hitPoint) + "<br/>";
    message += "攻撃力  :" + "%5.2f".sprintf(player.attackPoint) + "<br/>";
    message += "防御力  :" + "%5.2f".sprintf(player.defencePoint) + "<br/>";
    message += "すばやさ:" + "%5.2f".sprintf(player.quicknessPoint);
    message += "</code>";
    return message;
}

// 文字列からハッシュ値を計算します
// stringValue: ハッシュ値を求める文字列
function calculateHash(stringValue)
{
//    return crc.hex(stringValue, 16);
    var hashValue = 0;
    
    for(i=0 ; i<stringValue.length ; i++) {
        hashValue = 31 * hashValue + stringValue.charCodeAt(i);
        hashValue &= 0xffff;
    }
    
    // 下位2byteのみほしい。
    var result = hashValue & 0xffff;
    var hashStr = result.toString(16);
    
    while(hashStr.length < 4) {
        hashStr = "0" + hashStr;
    }
    
    // 配列に変換(IE7対応)
    var hashArray = [];

    for(i=0 ; i<hashStr.length ; i++)
    {
        hashArray[i] = hashStr.charAt(i);
    }
    
    return hashArray;
}

// 戦闘を行います。
// player1: 先攻プレイヤ
// player2: 後攻プレイヤ
function beginBattle(player1, player2, logTarget)
{
    logTarget.value = "戦闘開始！\n";
    
    // すばやさの合計
    var totalQuickness = player1.quicknessPoint + player2.quicknessPoint;
    player1.attackProbability = player1.quicknessPoint / totalQuickness;
    player2.attackProbability = player2.quicknessPoint / totalQuickness;
    
    // 最大maxTurn回の攻防を行う
    var winnerExists = false;
    for(i=0 ; i<g_context.maxTurn ; i++) 
    {
        // player1の攻撃
        processBattlePhase(player1, player2, logTarget);
        if(player2.hitPoint <= 0) {
            logTarget.value += "'%s'の勝利！\n".sprintf(player1.name);
            winnerExists = true;
            break;
        }
        
        // player2の攻撃
        processBattlePhase(player2, player1, logTarget);
        if(player1.hitPoint <= 0) {
            logTarget.value += "'%s'の勝利！\n".sprintf(player2.name);
            winnerExists = true;
            break;
        }
    }
    if(!winnerExists) logTarget.value += "引き分け";
}

// 1ターンの処理(1ターン=あるプレイヤが攻撃を行い、他のプレイヤが防御を行うことを１単位とする)
// attackerPlayer: 攻撃側Player (class Player)
// defenderPlayer: 防御側Player (class Player)
function processBattlePhase(attackerPlayer, defenderPlayer, logTarget)
{
    // attackerPlayerの攻撃
    logTarget.value += "プレイヤ '%s' の攻撃！\n".sprintf(attackerPlayer.name);
    var damageToDefender = 0;
    damageToDefender = attackerPlayer.attackPoint - defenderPlayer.defencePoint;
    if(damageToDefender <= 0) damageToDefender = 1;

    if(Math.random() <= attackerPlayer.attackProbability) {
        // 攻撃成功
        defenderPlayer.hitPoint -= damageToDefender;
        logTarget.value += " ⇒'%s'に%5.3fのダメージを与えました。\n".sprintf(defenderPlayer.name, damageToDefender);
    } else {
        // 攻撃失敗
        logTarget.value += " ⇒攻撃失敗。\n";
    }
}
