ソツケンの要旨を提出してなんとかした。



これで、エナジーが1しか無い時でも、エナジーベリーを発動できるようになりました。
pub fn select_hand(
mut select_hand_event_reader: EventReader<SelectHand>,
player1_hand: ResMut<Player1Hand>,
player1_szone: ResMut<Player1SZone>,
mut check_played_card_type_event_writer: EventWriter<CheckPlayedCardType>,
query: Query<(Entity, &Card, &SpinCondition), With<Player1>>,
query_option: Query<(Entity, &Card, Option<&Fighter>, Option<&Tactics>)>,
mut main_phase_management_event_writer: EventWriter<MainPhaseManagement>,
) {
for event in select_hand_event_reader.read() {
let total_energy_in_szone_respin: u32 = player1_szone
.cards
.filter_map(|entity| {
if let Ok*1 = query.get(*entity) {
if let SpinCondition::ReSpin = spincondition {
Some(card.energy) // リスピン中のカードのエナジーを取得
} else {
None
}
} else {
None
}
})
.sum();
println!(
"現在のSゾーンのリスピン状態のカードの合計エナジー: {}",
total_energy_in_szone_respin
);
// 手札のカードの情報を番号付きで表示
println!("手札のカード:[エナジー(タクティクスの必要エナジーは表示されません)]");
for (index, &entity) in player1_hand.cards.iter().enumerate() {
if let Ok*2 = query.get(entity) {
println!("{}: {} [{}]", index + 1, card.name, card.energy);
}
}
// ユーザーからの入力を受け取る
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
if let Ok(selected_index) = input.trim().parse::<usize>() {
if selected_index > 0 && selected_index <= player1_hand.cards.len() {
let selected_entity = player1_hand.cards[selected_index - 1];
query_option.get(selected_entity)
{
println!("{} はタクティクスです。", card.name);
if tactics.required_energy <= total_energy_in_szone_respin {
println!("{} を選択しました。", card.name);
check_played_card_type_event_writer.send(CheckPlayedCardType {
played_card_id: selected_entity,
});
} else {
println!(
"選択したタクティクスの必要エナジーが合計エナジーを超えています。再度選択してください。"
);
main_phase_management_event_writer.send(MainPhaseManagement);
}
} else {
// ファイターの場合の処理
if card.energy <= total_energy_in_szone_respin {
println!("{} を選択しました。", card.name);
check_played_card_type_event_writer.send(CheckPlayedCardType {
played_card_id: selected_entity,
});
} else {
println!(
"選択したファイターのエナジーが合計エナジーを超えています。再度選択してください。"
);
main_phase_management_event_writer.send(MainPhaseManagement);
}
}
} else {
println!("無効な選択です。");
main_phase_management_event_writer.send(MainPhaseManagement);
}
} else {
println!("無効な選択です。");
main_phase_management_event_writer.send(MainPhaseManagement);
}
} else {
println!("有効な番号を入力してください。");
}
}
}
もともとエナジーの検討しかしてなかったけど、エナジーベリーのような必要エナジーの方が少ない場合もあることに気付いて、変えたんだよね。
で、0や他の数字を押した時のデバッグもしてきます。

あとは数値を入力する関数を上から直していきます。

0を入力すると、選択が全部終わった後マネジメントが起動するようになってしまっていて、上手くいってない。
pub fn play_fighter_spin_szone(
player1_szone: ResMut<Player1SZone>,
mut play_fighter_spin_szone_event_reader: EventReader<PlayFighterSpinSzone>,
query: Query<(Entity, &Card, &SpinCondition), With<Player1>>,
mut commands: Commands,
mut main_phase_management_event_writer: EventWriter<MainPhaseManagement>,
mut select_hand_event_writer: EventWriter<SelectHand>,
mut play_fighter_from_hand_event_writer: EventWriter<PlayFighterFromHand>,
) {
for event in play_fighter_spin_szone_event_reader.read() {
let mut available_cards = Vec::new();
let mut spin_targets: Vec<Entity> = Vec::new();
let mut used_energy_for_fighter = 0;
let energy: u32 = if let Ok*4 = query.get(event.played_card_id) {
card.energy
} else {
// played_cardが無効な場合の処理
println!("無効なplayed_cardです。");
continue; // 次のイベントに進む
};
// Sゾーンのカードをリストアップ
for &entity in &player1_szone.cards {
if let Ok*5 = query.get(entity) {
if let SpinCondition::ReSpin = spincondition {
available_cards.push(entity);
println!(
"{}: {} (Sゾーン)[{}]",
available_cards.len(),
card.name,
card.energy
);
}
}
}
// played_cardのエナジーが0の場合の処理
if energy == 0 {
println!("played_cardのエナジーが0です。");
// エナジーが0の場合の独自のロジックをここに追加
continue; // または、特定の処理を実行
}
// 選択ループ
while used_energy_for_fighter < energy {
println!(
"スピンさせるカードを選択してください (1-{}) 0:やりなおす",
available_cards.len()
);
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
if let Ok(selected_index) = input.trim().parse::<usize>() {
if selected_index > 0 && selected_index <= available_cards.len() {
let selected_entity = available_cards[selected_index - 1];
// すでに選択されたカードか確認
if spin_targets.contains(&selected_entity) {
println!("このカードはすでに選択されています。");
continue; // 再選択を促す
}
if let Ok*6 = query.get(selected_entity) {
// スピンさせるカードのリストを作る
spin_targets.push(selected_entity);
used_energy_for_fighter += card.energy;
println!(
"{} をスピンさせる対象として追加しました (現在の合計エナジー: {})",
card.name, used_energy_for_fighter
);
}
} else {
println!("無効な選択です。");
main_phase_management_event_writer.send(MainPhaseManagement);
}
} else {
println!("有効な番号を入力してください。");
}
}
println!(
"合計エナジーが達成されました。スピン対象: {:?}",
spin_targets
);
for target in &spin_targets {
if let Ok*7 = query.get(*target) {
println!("- {} [エナジー: {}]", card.name, card.energy);
}
}
let choice = check_the_will_of_spinning_cards();
match choice {
1 => {
//エレメントについての言及は全くしていないことに注意!!
println!("スピンさせました。");
for target in &spin_targets {
commands.entity(*target).insert(SpinCondition::Spin);
}
play_fighter_from_hand_event_writer.send(PlayFighterFromHand {
played_card_id: event.played_card_id,
spin_cards_list: spin_targets,
});
}
2 => {
println!("やり直します");
select_hand_event_writer.send(SelectHand);
}
_ => {}
}
// 今後の処理をここに追加(例: スピン実行など)
}
}
while used_energy_for_fighter < energy {
println!(
"スピンさせるカードを選択してください (1-{}) 0:やりなおす",
available_cards.len()
);
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
if let Ok(selected_index) = input.trim().parse::<usize>() {
if selected_index == 0 {
println!("選択をキャンセルし、メインフェーズに戻ります。");
main_phase_management_event_writer.send(MainPhaseManagement);
return; // ループを抜ける
}
if selected_index > 0 && selected_index <= available_cards.len() {
let selected_entity = available_cards[selected_index - 1];
// すでに選択されたカードか確認
if spin_targets.contains(&selected_entity) {
println!("このカードはすでに選択されています。");
continue; // 再選択を促す
}
if let Ok*8 = query.get(selected_entity) {
// スピンさせるカードのリストを作る
spin_targets.push(selected_entity);
used_energy_for_fighter += card.energy;
println!(
"{} をスピンさせる対象として追加しました (現在の合計エナジー: {})",
card.name, used_energy_for_fighter
);
}
} else {
println!("無効な選択です。");
}
} else {
println!("有効な番号を入力してください。");
}
}
whileのなかをこういう風に変えた。

0で戻れるし、3打っても複数のイベントが出たりしてない。
この関数はOKってことにする。
同様のタクティクス関数についても書いていく。
player1_szone: ResMut<Player1SZone>,
mut play_tactics_spin_szone_event_reader: EventReader<PlayTacticsSpinSzone>,
query: Query<(Entity, &Card, &SpinCondition, &Tactics), With<Player1>>,
query2: Query<(Entity, &Card, &SpinCondition), With<Player1>>,
mut commands: Commands,
mut main_phase_management_event_writer: EventWriter<MainPhaseManagement>,
mut select_hand_event_writer: EventWriter<SelectHand>,
mut play_tactics_from_hand_event_writer: EventWriter<PlayTacticsFromHand>,
mut energy_adjustment_event_writer: EventWriter<EnergyAdjustment>,
) {
for event in play_tactics_spin_szone_event_reader.read() {
let mut available_cards = Vec::new();
let mut spin_targets: Vec<Entity> = Vec::new();
let mut used_energy_for_tactics = 0;
//Sゾーンのカードのエナジーの合計をスピンコンディション関係なく取得。
let mut total_energy_in_szone: u32 = player1_szone
.cards
.filter_map(|entity| {
if let Ok*9 = query2.get(*entity) {
Some(card.energy) // リスピン中のカードのエナジーを取得
} else {
None
}
})
.sum();
let energy: u32 = if let Ok*10 = query.get(event.played_card_id) {
} else {
// played_cardが無効な場合の処理
println!("無効なplayed_cardです。");
continue; // 次のイベントに進む
};
// Sゾーンのカードをリストアップ
for &entity in &player1_szone.cards {
if let Ok*11 = query2.get(entity) {
if let SpinCondition::ReSpin = spincondition {
available_cards.push(entity);
println!(
"{}: {} (Sゾーン)[{}]",
available_cards.len(),
card.name,
card.energy
);
}
}
}
// played_cardのエナジーが0の場合の処理
if energy == 0 {
println!("played_cardのエナジーが0です。");
// エナジーが0の場合の独自のロジックをここに追加
continue; // または、特定の処理を実行
}
// 選択ループ
while used_energy_for_tactics < energy {
println!(
"スピンさせるカードを選択してください (1-{}) 0:やりなおす",
available_cards.len()
);
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
if let Ok(selected_index) = input.trim().parse::<usize>() {
if selected_index > 0 && selected_index <= available_cards.len() {
let selected_entity = available_cards[selected_index - 1];
// すでに選択されたカードか確認
if spin_targets.contains(&selected_entity) {
println!("このカードはすでに選択されています。");
continue; // 再選択を促す
}
if let Ok*12 = query2.get(selected_entity) {
// スピンさせるカードのリストを作る
spin_targets.push(selected_entity);
used_energy_for_tactics += card.energy;
println!(
"{} をスピンさせる対象として追加しました (現在の合計使用エナジー: {})",
);
}
} else {
println!("無効な選択です。");
main_phase_management_event_writer.send(MainPhaseManagement);
}
} else {
println!("有効な番号を入力してください。");
}
}
println!(
"合計エナジーが達成されました。スピン対象: {:?}",
spin_targets
);
if let Ok*13 = query2.get(event.played_card_id) {
total_energy_in_szone += card.energy;
println!(
"プレイするタクティクスも含めたエナジーは{}です。",
total_energy_in_szone
);
}
for target in &spin_targets {
if let Ok*14 = query2.get(*target) {
println!("スピン予定のカード:");
println!("- {} [エナジー: {}]", card.name, card.energy);
}
}
if total_energy_in_szone > 10 {
println!("エナジーの調整が発生します。");
let choice = check_the_will_of_spinning_cards();
match choice {
1 => {
//エレメントについての言及は全くしていないことに注意!!
println!("スピンさせました。");
for target in &spin_targets {
commands.entity(*target).insert(SpinCondition::Spin);
}
let penalty = total_energy_in_szone - 10;
println!("送信するペナルティエナジー: {}", penalty);
energy_adjustment_event_writer.send(EnergyAdjustment {
played_card_id: event.played_card_id,
spin_cards_list: spin_targets,
penalty_energy: penalty,
});
}
2 => {
println!("やり直します");
select_hand_event_writer.send(SelectHand);
}
_ => {}
}
} else {
for target in &spin_targets {
if let Ok*15 = query2.get(*target) {
println!("- {} [エナジー: {}]", card.name, card.energy);
}
}
let choice = check_the_will_of_spinning_cards();
match choice {
1 => {
//エレメントについての言及は全くしていないことに注意!!
println!("スピンさせました。");
for target in &spin_targets {
commands.entity(*target).insert(SpinCondition::Spin);
}
play_tactics_from_hand_event_writer.send(PlayTacticsFromHand {
played_card_id: event.played_card_id,
spin_cards_list: spin_targets,
});
}
2 => {
println!("やり直します");
select_hand_event_writer.send(SelectHand);
}
_ => {}
}
}
}
}
先ほどと同じ問題があったので、0を選んだ時のループ破壊と、
無効な選択をしたときの、イベント送信をやめました。

変な選択入力は大丈夫なんだけど、
何故か同じカードが2枚表示されるのはよくわからん。
と思ったけど、よく見たら同じことやってるprintln!が二つあった。
for target in &spin_targets {
if let Ok*16 = query2.get(*target) {
println!("- {} [エナジー: {}]", card.name, card.energy);
}
}
if total_energy_in_szone > 10 {
println!("エナジーの調整が発生します。");
let choice = check_the_will_of_spinning_cards();
match choice {
1 => {
//エレメントについての言及は全くしていないことに注意!!
println!("スピンさせました。");
for target in &spin_targets {
commands.entity(*target).insert(SpinCondition::Spin);
}
let penalty = total_energy_in_szone - 10;
println!("送信するペナルティエナジー: {}", penalty);
energy_adjustment_event_writer.send(EnergyAdjustment {
played_card_id: event.played_card_id,
spin_cards_list: spin_targets,
penalty_energy: penalty,
});
}
2 => {
println!("やり直します");
select_hand_event_writer.send(SelectHand);
}
_ => {}
}
} else {
for target in &spin_targets {
if let Ok*17 = query2.get(*target) {
println!("- {} [エナジー: {}],", card.name, card.energy);
}
}
べつに一個でいいしな else{の中にあるやつを消した。


ペナルティが発生する時もしない時もきれいに表示されている。
ペナルティの関数の調整はいいや。

と思ったけど、0はダメだー。元のコードは全然読めなかったから、GPTに書かせた。
pub fn energy_adjustment(
mut energy_adjustment_event_reader: EventReader<EnergyAdjustment>,
player1_szone: ResMut<Player1SZone>,
query: Query<(Entity, &Card), (With<Player1>, Without<FirstEnergy>)>,
mut commands: Commands,
mut tactics_with_penalty_event_writer: EventWriter<PlayTacticsWithPenaltyFromHand>,
mut select_hand_event_writer: EventWriter<SelectHand>,
) {
for event in energy_adjustment_event_reader.read() {
let mut selected_cards: Vec<Entity> = Vec::new();
let mut total_energy_for_penalty: u32 = 0;
let penalty_energy = event.penalty_energy;
// Sゾーンのカードを取得
let available_cards: Vec<(Entity, &Card)> = player1_szone
.cards
.filter_map(|&entity| query.get(entity).ok())
.collect();
let high_energy_cards: Vec<(Entity, &Card)> = available_cards
.filter(|(_, card)| card.energy >= penalty_energy)
.cloned()
.collect();
if !high_energy_cards.is_empty() {
println!("ペナルティエナジー以上のカードがあります。選択可能なカード:");
for (index, (entity, card)) in high_energy_cards.iter().enumerate() {
println!("{}: {} [エナジー: {}]", index + 1, card.name, card.energy);
}
// ユーザーにカードを選ばせる
loop {
// 無効な選択時に再入力を促すループ
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
if let Ok(selected_index) = input.trim().parse::<usize>() {
if selected_index > 0 && selected_index <= high_energy_cards.len() {
let selected_entity = high_energy_cards[selected_index - 1].0;
selected_cards.push(selected_entity);
if let Ok*18 = query.get(selected_entity) {
total_energy_for_penalty += card.energy;
println!("選択したカード: {} [エナジー: {}]", card.name, card.energy);
}
break; // 有効な選択がされたらループを抜ける
} else {
println!("無効な選択です。再度選択してください。");
}
} else {
println!("有効な番号を入力してください。再度選択してください。");
}
}
} else {
println!("ペナルティエナジー以上のカードはありません。全てのカードを表示します。");
for (index, (entity, card)) in available_cards.iter().enumerate() {
println!("{}: {} [エナジー: {}]", index + 1, card.name, card.energy);
}
// ユーザーにカードを選ばせる
while total_energy_for_penalty <= penalty_energy {
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line");
if let Ok(selected_index) = input.trim().parse::<usize>() {
if selected_index > 0 && selected_index <= available_cards.len() {
let selected_entity = available_cards[selected_index - 1].0;
// 既に選択されたカードか確認
if !selected_cards.contains(&selected_entity) {
selected_cards.push(selected_entity);
if let Ok*19 = query.get(selected_entity) {
total_energy_for_penalty += card.energy;
println!(
"選択したカード: {} [エナジー: {}]",
card.name, card.energy
);
}
} else {
println!("このカードは既に選択されています。");
}
} else {
println!("無効な選択です。再度選択してください。");
}
} else {
println!("有効な番号を入力してください。再度選択してください。");
}
println!(
total_energy_for_penalty, penalty_energy
);
if total_energy_for_penalty > penalty_energy {
}
// 再度ペナルティエナジー以上のカードがあるか確認
let high_energy_cards: Vec<(Entity, &Card)> = available_cards
.filter(|(_, card)| card.energy >= penalty_energy - total_energy_for_penalty)
.cloned()
.collect();
if !high_energy_cards.is_empty() {
println!("ペナルティエナジーの差以上のカードがあります。選択可能なカード:");
for (index, (entity, card)) in high_energy_cards.iter().enumerate() {
println!("{}: {} [エナジー: {}]", index + 1, card.name, card.energy);
}
}
}
}
// 最終的に選んだカードのリストを表示
println!("最終的に選ばれたカード:");
for entity in selected_cards.clone() {
if let Ok*20 = query.get(entity) {
println!("- {} [エナジー: {}]", card.name, card.energy);
}
}
println!("ペナルティを受け入れますか?");
let choice = check_the_will_of_spinning_cards();
match choice {
1 => {
for entity in selected_cards.clone() {
commands.entity(entity).insert(Location::XZone);
commands.entity(entity).insert(SpinCondition::ReSpin);
commands.entity(entity).insert(FaceCondition::Facedown);
}
tactics_with_penalty_event_writer.send(PlayTacticsWithPenaltyFromHand {
played_card_id: event.played_card_id,
spin_cards_list: event.spin_cards_list.clone(),
penalty_card_list: selected_cards.clone(),
});
}
2 => {
println!("やりなおします");
for target in &event.spin_cards_list {
commands.entity(*target).insert(SpinCondition::ReSpin);
}
println!("スピンしたカードを元に戻しました。");
select_hand_event_writer.send(SelectHand);
}
_ => {}
}
// 意思決定関数を入れた
}
}

OK
これで、数字入力する系の修正作業は終わりです。
pub struct FreePlugin;
impl Plugin for FreePlugin {
fn build(&self, app: &mut App) {
app.add_event::<SituationLog>()
.add_event::<MainPhaseManagement>()
.add_event::<ContinueMainPhase>()
.add_systems(
Update,
(situation_log, main_phase_management, continue_main_phase),
);
}
}
freeの二人プレー化を進める。
pub fn situation_log(
mut hand: ResMut<Player1Hand>,
mut szone: ResMut<Player1SZone>,
mut fzone: ResMut<Player1FZone>,
mut xzone: ResMut<Player1XZone>,
mut szone_opponent: ResMut<Player2SZone>,
mut fzone_opponent: ResMut<Player2FZone>,
mut xzone_opponent: ResMut<Player2XZone>,
query: Query<(Entity, &Card, &Location), With<Player1>>,
query_opponent: Query<(Entity, &Card, &Location), With<Player2>>,
query_first_energy: Query<(Entity, &Card), (With<Player1>, With<FirstEnergy>)>,
query_first_energy_opponent: Query<(Entity, &Card), (With<Player2>, With<FirstEnergy>)>,
mut next_state: ResMut<NextState<GameState>>,
mut check_event_reader: EventReader<SituationLog>,
mut continue_main_phase_event_writer: EventWriter<ContinueMainPhase>,
mut game_over_event_writer: EventWriter<GameOver>,
mut commands: Commands,
) {
for _event in check_event_reader.read() {
// プレイヤー1の手札をチェック
hand.cards.clear();
fzone.cards.clear();
szone.cards.clear();
xzone.cards.clear();
for (entity, card, location) in query.iter() {
if let Location::InHand = location {
hand.cards.push(entity);
}
if let Location::SZone = location {
szone.cards.push(entity);
}
if let Location::FZone = location {
fzone.cards.push(entity);
}
if let Location::XZone = location {
xzone.cards.push(entity);
}
}
// プレイヤー2のSゾーンとFゾーンをチェック
szone_opponent.cards.clear();
fzone_opponent.cards.clear();
xzone_opponent.cards.clear();
for (entity, card, location) in query_opponent.iter() {
if let Location::SZone = location {
szone_opponent.cards.push(entity);
}
if let Location::FZone = location {
fzone_opponent.cards.push(entity);
}
if let Location::XZone = location {
xzone_opponent.cards.push(entity);
}
}
println!("--- フィールド情報 ---");
println!("プレイヤー1の手札: {:?}", hand.cards);
println!("プレイヤー1のSゾーン: {:?}", szone.cards);
println!("プレイヤー1のFゾーン: {:?}", fzone.cards);
println!("プレイヤー1のXゾーン: {:?}", xzone.cards);
println!("プレイヤー2のSゾーン: {:?}", szone_opponent.cards);
println!("プレイヤー2のFゾーン: {:?}", fzone_opponent.cards);
println!("プレイヤー2のXゾーン: {:?}", xzone_opponent.cards);
if xzone.cards.len() >= 6 {
println!("プレイヤー1のXゾーンには6枚以上のカードがあります。");
for (entity, card) in query_first_energy.iter() {
commands.entity(entity).insert(Location::XZone);
println!("プレイー1の{}がXゾーンに置かれました。", card.name);
}
game_over_event_writer.send(GameOver {
winner_id: 2,
});
next_state.set(GameState::GameOver);
}
if xzone_opponent.cards.len() >= 6 {
println!("プレイヤー2のXゾーンには6枚以上のカードがあります。");
for (entity, card) in query_first_energy_opponent.iter() {
commands.entity(entity).insert(Location::XZone);
println!("プレイー2の{}がXゾーンに置かれました。", card.name);
}
game_over_event_writer.send(GameOver {
winner_id: 1,
});
next_state.set(GameState::GameOver);
}
println!("フィールド情報の更新をしました");
continue_main_phase_event_writer.send(ContinueMainPhase);
}
}
わかりにくかった、player1_fzoneなどを、相対的な単語にした。
これで、コピペで引数を変えればよくなる。
.add_systems(
Update,
(situation_log, main_phase_management, continue_main_phase).run_if(in_state(Controller::Player)),
).add_systems(
Update,
(situation_log_opponent, main_phase_management, continue_main_phase).run_if(in_state(Controller::Opponent)),
)
こういう風に直した。

上手くいったわー
バトルとプレイの2人化は明日に回します。