// © Copyright 1999, Joseph Bergin.  All rights reserved. package gates;import cs1.Die;class Gate	// Constant output gate{	public Gate() {} // true gate	public Gate(boolean b){output = b;}		public boolean output(){return output;}		public void connect(Gate g){} // nothing		private boolean output = true;	protected void output(boolean b)	{output = b;}}class Switch extends Gate{	public Switch(){} // initially true = ON	public Switch(boolean b){super(b);}	public void flip(){output(!output());}}class UnaryGate extends Gate //pass thru and root of unary gate hierarchy{	public UnaryGate(){}	public UnaryGate(Gate input){this.input = input;}	public void connect(Gate input){this.input = input;}		public boolean output()	{	if(input != null)return input.output();		return (new Die(2)).roll() == 0; // random output if not connected. 	} 	private Gate input = null;}class NotGate extends UnaryGate // Flips its input{	public NotGate(){}	public NotGate(Gate input){super(input);}		public boolean output()	{	return ! super.output();	}}abstract class BinaryGate extends Gate // root of binary gate hierarchy{	public BinaryGate(){}	public BinaryGate(Gate left, Gate right){leftInput = left; rightInput = right;}	public void connect(Gate g)	{	if(leftInput == null)			leftInput = g;		else			rightInput = g;	}		private Gate leftInput = null, rightInput = null;	protected boolean left()	{	if(leftInput != null)return leftInput.output();		return false;	}		protected boolean right()	{	if(rightInput != null)return rightInput.output();		return false;	}}class AndGate extends BinaryGate{	public AndGate(){}	public AndGate(Gate left, Gate right){super(left,right);}		public boolean output()	{	return left() && right();	}}class OrGate extends BinaryGate{	public OrGate(){}	public OrGate(Gate left, Gate right){super(left,right);}		public boolean output()	{	return left() || right();	}}public class GateTest {	public static void main(String args[]) 	{	Switch TG = new Switch(true);		Switch FG = new Switch(false);		AndGate And1 = new AndGate(TG, FG);		OrGate Or1 = new OrGate(And1, FG);		NotGate Not1 = new NotGate(Or1);				System.out.println(Not1.output());		FG.flip();		System.out.println(Not1.output());		TG.flip();		System.out.println(Not1.output());		FG.flip();		System.out.println(Not1.output());				TG.flip();		FG.flip();		Adder add = new Adder(TG, FG);		System.out.println("Adder " + add.output()[0] + " " + add.output()[1]);		try 		{	System.in.read(); // prevent console window from going away		} catch (java.io.IOException e) {}	}}