Skip to content

Commit

Permalink
Implement Miscast
Browse files Browse the repository at this point in the history
Fixes #57
  • Loading branch information
radar committed Jan 18, 2024
1 parent 710b7d7 commit 821ab3a
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
50 changes: 50 additions & 0 deletions lib/magic/cards/miscast.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module Magic
module Cards
Miscast = Instant("Miscast") do
cost blue: 1, generic: 1
end

class Miscast < Instant
class Choice < Magic::Choice::Effect
attr_reader :source, :target
def initialize(source:, target:)
super(target.player)
@source = source
@target = target
end

def inspect
"#<Miscast::Counter target spell source:#{source}, target:#{target}>"
end

def costs
@costs ||= [Costs::Mana.new(generic: 3)]
end

def pay(player, payment)
cost = costs.first
cost.pay!(player, payment)
end

def resolve!
if costs.none?(&:paid?)
effect = Effects::CounterSpell.new(source: source, targets: [target], choices: [target])
game.add_effect(effect)
end
end
end

def single_target?
true
end

def target_choices
game.stack
end

def resolve!(target:)
game.choices.add(Choice.new(source: self, target:))
end
end
end
end
47 changes: 47 additions & 0 deletions spec/cards/miscast_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'spec_helper'

RSpec.describe Magic::Cards::Miscast do
include_context "two player game"

subject(:miscast) { Card("Miscast") }

context "with miscast on the stack" do
let(:sol_ring) { Card("Sol Ring", owner: p2) }

before do
p2.add_mana(blue: 1)
sol_ring_cast = p2.cast(card: sol_ring) do
_1.pay_mana(generic: { blue: 1 })
end

p1.add_mana(blue: 2)
p1.cast(card: miscast) do
_1.pay_mana(generic: { blue: 1}, blue: 1)
_1.targeting(sol_ring_cast)
end
game.tick!
end

it "has a 3 cost choice" do
choice = game.choices.first
expect(choice.costs.first.generic).to eq(3)
end

it "counters target spell if cost is unpaid" do
game.resolve_choice!
game.tick!

expect(sol_ring.zone).to be_graveyard
end

it "does not counter spell if cost is paid" do
choice = game.choices.first
p2.add_mana(white: 3)
choice.pay(p2, generic: { white: 3 })

game.resolve_choice!
game.tick!
expect(sol_ring.zone).to be_battlefield
end
end
end

0 comments on commit 821ab3a

Please sign in to comment.