Compare commits

..

No commits in common. "a1c74b64c0584dae538e483dacfeadce60460bb9" and "850fb7e4a276cfa5cc12c4c9c14c108d3c4c5150" have entirely different histories.

39 changed files with 197 additions and 753 deletions

View File

@ -1,12 +1,3 @@
v2o.4.7
+ Added quantum computer Python Qiskit code generation
* Code is now generated by using a code generator component rather than the controller
+ Added salt to recipe hash caching to avoid clashes (salt is incremented if a clash occurs and hashes are recalculated)
* Fixed broken quantum computer component recipes
v2o.4.6
+ Added huge glowing mushrooms
@ -23,7 +14,7 @@ v2o.4.6
v2o.4.5
+ Added WIP QASM code generation mode to quantum computers for use with IBM Q
+ Added WIP OpenQASM code generation mode to quantum computers
* Fixed crash on placing Rock Crusher

View File

@ -1,7 +1,7 @@
mc_version=1.12.2
forge_version=14.23.5.2847
mapping_version=stable_39
mod_version=2o.4.7
mod_version=2o.4.6
ic2_version=2.8.197-ex112
jei_version=4.15.0.293

View File

@ -224,7 +224,7 @@ public class NCConfig {
public static double accelerator_supercooler_coolant;
public static int quantum_max_qubits_live;
public static int quantum_max_qubits_code;
public static int quantum_max_qubits_qasm;
public static int quantum_angle_precision;
public static int[] tool_mining_level;
@ -758,8 +758,8 @@ public class NCConfig {
Property propertyQuantumMaxQubitsLive = config.get(CATEGORY_QUANTUM, "quantum_max_qubits_live", 7, Lang.localise("gui.nc.config.quantum_max_qubits_live.comment"), 1, 14);
propertyQuantumMaxQubitsLive.setLanguageKey("gui.nc.config.quantum_max_qubits_live");
Property propertyQuantumMaxQubitsCode = config.get(CATEGORY_QUANTUM, "quantum_max_qubits_code", 16, Lang.localise("gui.nc.config.quantum_max_qubits_code.comment"), 1, 32);
propertyQuantumMaxQubitsCode.setLanguageKey("gui.nc.config.quantum_max_qubits_code");
Property propertyQuantumMaxQubitsQasm = config.get(CATEGORY_QUANTUM, "quantum_max_qubits_qasm", 16, Lang.localise("gui.nc.config.quantum_max_qubits_qasm.comment"), 1, 32);
propertyQuantumMaxQubitsQasm.setLanguageKey("gui.nc.config.quantum_max_qubits_qasm");
Property propertyQuantumAnglePrecision = config.get(CATEGORY_QUANTUM, "quantum_angle_precision", 16, Lang.localise("gui.nc.config.quantum_angle_precision.comment"), 2, 5760);
propertyQuantumAnglePrecision.setLanguageKey("gui.nc.config.quantum_angle_precision");
@ -1216,7 +1216,7 @@ public class NCConfig {
List<String> propertyOrderQuantum = new ArrayList<>();
propertyOrderQuantum.add(propertyQuantumMaxQubitsLive.getName());
propertyOrderQuantum.add(propertyQuantumMaxQubitsCode.getName());
propertyOrderQuantum.add(propertyQuantumMaxQubitsQasm.getName());
propertyOrderQuantum.add(propertyQuantumAnglePrecision.getName());
config.setCategoryPropertyOrder(CATEGORY_QUANTUM, propertyOrderQuantum);
@ -1540,7 +1540,7 @@ public class NCConfig {
accelerator_supercooler_coolant = propertyAcceleratorSupercoolerCoolant.getDouble();
quantum_max_qubits_live = propertyQuantumMaxQubitsLive.getInt();
quantum_max_qubits_code = propertyQuantumMaxQubitsCode.getInt();
quantum_max_qubits_qasm = propertyQuantumMaxQubitsQasm.getInt();
quantum_angle_precision = propertyQuantumAnglePrecision.getInt();
tool_mining_level = readIntegerArrayFromConfig(propertyToolMiningLevel);
@ -1864,7 +1864,7 @@ public class NCConfig {
propertyAcceleratorSupercoolerCoolant.set(accelerator_supercooler_coolant);
propertyQuantumMaxQubitsLive.set(quantum_max_qubits_live);
propertyQuantumMaxQubitsCode.set(quantum_max_qubits_code);
propertyQuantumMaxQubitsQasm.set(quantum_max_qubits_qasm);
propertyQuantumAnglePrecision.set(quantum_angle_precision);
propertyToolMiningLevel.set(tool_mining_level);

View File

@ -193,8 +193,6 @@ public class NCBlocks {
public static Block quantum_computer_connector;
public static Block quantum_computer_code_generator;
public static void init() {
ore = withName(new BlockMeta.BlockOre(), "ore");
ingot_block = withName(new BlockMeta.BlockIngot(), "ingot_block");
@ -396,8 +394,6 @@ public class NCBlocks {
quantum_computer_gate_swap = withName(new BlockQuantumComputerGate.Swap(), "quantum_computer_gate_swap");
quantum_computer_connector = withName(new BlockQuantumComputerConnector(), "quantum_computer_connector");
quantum_computer_code_generator = withName(new BlockQuantumComputerCodeGenerator(), "quantum_computer_code_generator");
}
}
@ -603,8 +599,6 @@ public class NCBlocks {
registerBlock(quantum_computer_gate_swap, new ItemBlockMeta(quantum_computer_gate_swap, QuantumGateEnums.SwapType.class, TextFormatting.AQUA));
registerBlock(quantum_computer_connector);
registerBlock(quantum_computer_code_generator, new ItemBlockMeta(quantum_computer_code_generator, BlockQuantumComputerCodeGenerator.Type.class, TextFormatting.AQUA));
}
}
@ -841,10 +835,6 @@ public class NCBlocks {
}
registerRender(quantum_computer_connector);
for (int i = 0; i < BlockQuantumComputerCodeGenerator.Type.values().length; i++) {
registerRender(quantum_computer_code_generator, i, "type=" + BlockQuantumComputerCodeGenerator.Type.values()[i].getName());
}
}
}

View File

@ -11,7 +11,6 @@ import nc.multiblock.fission.tile.port.*;
import nc.multiblock.heatExchanger.HeatExchangerTubeType;
import nc.multiblock.heatExchanger.tile.*;
import nc.multiblock.qComputer.QuantumGateEnums;
import nc.multiblock.qComputer.block.BlockQuantumComputerCodeGenerator;
import nc.multiblock.qComputer.tile.*;
import nc.multiblock.rtg.tile.TileRTG;
import nc.multiblock.turbine.TurbineDynamoCoilType;
@ -296,8 +295,5 @@ public class NCTiles {
GameRegistry.registerTileEntity(TileQuantumComputerConnector.class, Global.MOD_ID + ":quantum_computer_connector");
GameRegistry.registerTileEntity(TileQuantumComputerPort.class, Global.MOD_ID + ":quantum_computer_port");
GameRegistry.registerTileEntity(TileQuantumComputerCodeGenerator.Qasm.class, Global.MOD_ID + ":quantum_computer_code_generator_" + BlockQuantumComputerCodeGenerator.Type.QASM.getName());
GameRegistry.registerTileEntity(TileQuantumComputerCodeGenerator.Qiskit.class, Global.MOD_ID + ":quantum_computer_code_generator_" + BlockQuantumComputerCodeGenerator.Type.QISKIT.getName());
}
}

View File

@ -1,6 +1,6 @@
# The MIT License (MIT)
Copyright (c) 2020 "tomdodd4598"
Copyright (c) 2016 "ZeroNoRyouki"
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -92,6 +92,5 @@ public final class MultiblockHandler {
QuantumComputer.PART_CLASSES.add(TileQuantumComputerController.class);
QuantumComputer.PART_CLASSES.add(TileQuantumComputerQubit.class);
QuantumComputer.PART_CLASSES.add(TileQuantumComputerCodeGenerator.class);
}
}

View File

@ -38,8 +38,8 @@ public class QuantumComputer extends Multiblock<IQuantumComputerPart, Multiblock
protected Queue<QuantumGate> queue = new ConcurrentLinkedQueue<>();
public int codeStart = -1, codeType = -1;
protected StringBuilder codeBuilder;
public boolean qasmStart = false, qasmWrite = false;
protected StringBuilder qasmStringBuilder = new StringBuilder();
public QuantumComputer(World world) {
super(world);
@ -82,7 +82,7 @@ public class QuantumComputer extends Multiblock<IQuantumComputerPart, Multiblock
}
public static int getMaxQubits() {
return Math.max(quantum_max_qubits_live, quantum_max_qubits_code);
return Math.max(quantum_max_qubits_live, quantum_max_qubits_qasm);
}
protected void onQuantumComputerFormed() {
@ -145,9 +145,9 @@ public class QuantumComputer extends Multiblock<IQuantumComputerPart, Multiblock
multiblock.setLastError(Global.MOD_ID + ".multiblock_validation.too_many_controllers", null);
return false;
}
int q = qubitCount(), max = getMaxQubits();
if (q > max) {
multiblock.setLastError(Global.MOD_ID + ".multiblock_validation.quantum_computer.too_many_qubits", null, q, max);
int q = qubitCount();
if (q > getMaxQubits()) {
multiblock.setLastError(Global.MOD_ID + ".multiblock_validation.quantum_computer.too_many_qubits", null, q, getMaxQubits());
return false;
}
@ -173,10 +173,10 @@ public class QuantumComputer extends Multiblock<IQuantumComputerPart, Multiblock
boolean refresh = false;
int q = qubitCount();
if (codeStart >= 0) {
codeType = codeStart;
codeStart = -1;
codeBuilder = new StringBuilder();
if (qasmStart) {
qasmStart = false;
qasmWrite = true;
qasmStringBuilder = new StringBuilder();
}
QuantumGate gate = queue.poll();
@ -198,15 +198,15 @@ public class QuantumComputer extends Multiblock<IQuantumComputerPart, Multiblock
}
}
if (codeType >= 0) {
if (q <= quantum_max_qubits_code) {
List<String> code = gate.getCode(codeType);
if (!code.isEmpty()) {
codeBuilder.append(IOHelper.NEW_LINE);
if (qasmWrite) {
if (q <= quantum_max_qubits_qasm) {
List<String> qasmCode = gate.qasmCode();
if (!qasmCode.isEmpty()) {
qasmStringBuilder.append(IOHelper.NEW_LINE);
}
for (String line : code) {
codeBuilder.append(line);
codeBuilder.append(IOHelper.NEW_LINE);
for (String line : qasmCode) {
qasmStringBuilder.append(line);
qasmStringBuilder.append(IOHelper.NEW_LINE);
}
}
}
@ -673,117 +673,44 @@ public class QuantumComputer extends Multiblock<IQuantumComputerPart, Multiblock
gate(m);
}
public void printCode(EntityPlayer player) {
if (codeType < 0) {
public void qasmPrint(EntityPlayer player) {
if (!qasmWrite) {
return;
}
int codeType = this.codeType;
this.codeType = -1;
qasmWrite = false;
int q = qubitCount();
if (q > quantum_max_qubits_code) {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.code_exit_too_many_qubits")));
if (q > quantum_max_qubits_qasm) {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.qasm_exit_too_many_qubits")));
return;
}
String codeString = codeBuilder.toString();
String s = IOHelper.NEW_LINE, d = s + s;
String qasmString = qasmStringBuilder.toString();
qasmStringBuilder = new StringBuilder();
if (codeType == 0) {
if (codeString.isEmpty()) {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.qasm_exit_empty")));
return;
}
File out = new File("nuclearcraft/quantum/qasm/" + q + "_qubit_" + System.currentTimeMillis() + ".qasm");
codeString = "OPENQASM 2.0;" + s +
"include \"qelib1.inc\";" + d +
"qreg q[" + q + "];" + s +
"creg c[" + q + "];" + s +
codeString;
ITextComponent link = new TextComponentString(out.getName());
link.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, out.getAbsolutePath())).setBold(true).setUnderlined(true);
try {
FileUtils.writeStringToFile(out, codeString);
player.sendMessage(new TextComponentTranslation("info.nuclearcraft.multitool.quantum_computer.controller.qasm_print", new Object[] {link}));
}
catch (IOException e) {
NCUtil.getLogger().catching(e);
player.sendMessage(new TextComponentTranslation("info.nuclearcraft.multitool.quantum_computer.controller.qasm_error", new Object[] {out.getAbsolutePath()}));
}
}
else if (codeType == 1) {
if (codeString.isEmpty()) {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.qiskit_exit_empty")));
return;
}
File out = new File("nuclearcraft/quantum/qiskit/" + q + "_qubit_" + System.currentTimeMillis() + ".ipynb");
codeString = "# Jupyter plot output mode" + s +
"%matplotlib inline" + d +
"# Standard Qiskit libraries" + s +
"from qiskit import *" + s +
"from qiskit.compiler import transpile, assemble" + s +
"from qiskit.providers.ibmq import least_busy" + s +
"from qiskit.visualization import *" + s +
"from qiskit.tools.monitor import job_monitor" + s +
"from qiskit.tools.jupyter import *" + d +
"# Python maths" + s +
"import numpy as np" + s +
"from numpy import pi" + d +
"# Number of qubits" + s +
"qubits = " + q + d +
"# Load IBMQ account" + s +
"provider = IBMQ.load_account()" + s +
"simulator = provider.get_backend('ibmq_qasm_simulator')" + s +
"device = provider.get_backend('ibmq_16_melbourne')" + s +
"# quiet = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= qubits" + s +
" # and not x.configuration().simulator" + s +
" # and x.status().operational==True))" + d +
"# Helper function" + s +
"def run_job(circ_, backend_, shots_ = 1024, optimization_level_ = 1):" + s +
" print('Using ', backend_)" + s +
" job = execute(circ_, backend=backend_, shots=shots_, optimization_level=optimization_level_)" + s +
" job_monitor(job)" + s +
" return job.result()" + d +
"# Construct circuit" + s +
"qc = QuantumCircuit(qubits, qubits)" + s +
codeString + s +
"# Run circuit" + s +
"result = run_job(qc, backend_=simulator)" + s +
"counts = result.get_counts(qc)" + s +
"print('\\n', counts)" + d +
"# Printing results" + s +
"# NOTE: only one diagram can be shown per Jupyter cell." + s +
"# Either comment out all but one drawing/plotting method" + s +
"# or move them into separate cells." + d +
"# Draw circuit" + s +
"# qc.draw()" + d +
"# Plot results" + s +
"# plot_histogram(counts)" + s;
ITextComponent link = new TextComponentString(out.getName());
link.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, out.getAbsolutePath())).setBold(true).setUnderlined(true);
try {
FileUtils.writeStringToFile(out, codeString);
player.sendMessage(new TextComponentTranslation("info.nuclearcraft.multitool.quantum_computer.controller.qiskit_print", new Object[] {link}));
}
catch (IOException e) {
NCUtil.getLogger().catching(e);
player.sendMessage(new TextComponentTranslation("info.nuclearcraft.multitool.quantum_computer.controller.qiskit_error", new Object[] {out.getAbsolutePath()}));
}
}
else {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.code_exit_empty")));
if (qasmString.isEmpty()) {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.qasm_exit")));
return;
}
codeString = null;
File out = new File("nuclearcraft/quantum/" + q + "_qubit_" + System.currentTimeMillis() + ".qasm");
String s = IOHelper.NEW_LINE;
qasmString = "OPENQASM 2.0;" + s + "include \"qelib1.inc\";" + s + s + "qreg q[" + q + "];" + s + "creg c[" + q + "];" + s + qasmString;
ITextComponent link = new TextComponentString(out.getName());
link.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, out.getAbsolutePath())).setBold(true).setUnderlined(true);
try {
FileUtils.writeStringToFile(out, qasmString);
player.sendMessage(new TextComponentTranslation("info.nuclearcraft.multitool.quantum_computer.controller.qasm_print", new Object[] {link}));
}
catch (IOException e) {
NCUtil.getLogger().catching(e);
player.sendMessage(new TextComponentTranslation("info.nuclearcraft.multitool.quantum_computer.controller.qasm_error", new Object[] {link}));
}
qasmString = "";
}
}

View File

@ -2,10 +2,9 @@ package nc.multiblock.qComputer;
import java.util.*;
import com.google.common.base.Strings;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.objects.*;
import joptsimple.internal.Strings;
import nc.util.*;
public abstract class QuantumGate<GATE extends QuantumGate> {
@ -47,7 +46,8 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
/** Adds the required decomposition of this gate to the list. */
public abstract void addRequiredDecomposition(List<QuantumGate> decomposition);
public abstract List<String> getCode(int type);
/** Lines of QASM Python code */
public abstract List<String> qasmCode();
public static class Measurement extends QuantumGate<Measurement> {
@ -105,23 +105,12 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
IntList l = list(n);
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < l.size(); i++) {
out.add("measure q[" + l.getInt(i) + "] -> c[" + l.getInt(i) + "];");
}
for (int i = 0; i < l.size(); i++) {
out.add("measure q[" + l.getInt(i) + "] -> c[" + l.getInt(i) + "];");
}
else if (type == 1) {
if (!l.isEmpty()) {
String s = pythonArray(l);
out.add("qc.barrier(" + s + ")");
out.add("qc.measure(" + s + ", " + s + ")");
}
}
return out;
}
}
@ -175,23 +164,12 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
int q = qc.qubitCount();
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < q; i++) {
out.add("reset q[" + i + "];");
}
for (int i = 0; i < q; i++) {
out.add("reset q[" + i + "];");
}
else if (type == 1) {
if (q != 0) {
String s = pythonArray(CollectionHelper.increasingList(q));
out.add("qc.barrier(" + s + ")");
out.add("qc.reset(" + s + ")");
}
}
return out;
}
}
@ -237,27 +215,16 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
IntList l = list(n);
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < l.size(); i++) {
out.add(qasmLine(l.getInt(i)));
}
for (int i = 0; i < l.size(); i++) {
out.add(qasmLine(l.getInt(i)));
}
else if (type == 1) {
if (!l.isEmpty()) {
out.add(qiskitLine(l));
}
}
return out;
}
public abstract String qasmLine(int i);
public abstract String qiskitLine(IntList l);
}
public static class X extends Basic {
@ -297,11 +264,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "x q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.x(" + pythonArray(l) + ")";
}
}
public static class Y extends Basic {
@ -341,11 +303,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "y q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.y(" + pythonArray(l) + ")";
}
}
public static class Z extends Basic {
@ -385,11 +342,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "z q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.z(" + pythonArray(l) + ")";
}
}
public static class H extends Basic {
@ -429,11 +381,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "h q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.h(" + pythonArray(l) + ")";
}
}
public static class S extends Basic {
@ -473,11 +420,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "s q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.s(" + pythonArray(l) + ")";
}
}
public static class Sdg extends Basic {
@ -517,11 +459,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "sdg q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.sdg(" + pythonArray(l) + ")";
}
}
public static class T extends Basic {
@ -561,11 +498,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "t q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.t(" + pythonArray(l) + ")";
}
}
public static class Tdg extends Basic {
@ -605,11 +537,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(int i) {
return "tdg q[" + i + "];";
}
@Override
public String qiskitLine(IntList l) {
return "qc.tdg(" + pythonArray(l) + ")";
}
}
public static abstract class BasicAngle extends QuantumGate<BasicAngle> {
@ -647,21 +574,12 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public abstract BasicAngle newMerged(double angle, IntSet c, IntSet t);
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
IntList l = list(n);
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < l.size(); i++) {
out.add(qasmLine(angle, l.getInt(i)));
}
for (int i = 0; i < l.size(); i++) {
out.add(qasmLine(angle, l.getInt(i)));
}
else if (type == 1) {
if (!l.isEmpty()) {
out.add(qiskitLine(angle, l));
}
}
return out;
}
@ -678,8 +596,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
public abstract String qasmLine(double angle, int i);
public abstract String qiskitLine(double angle, IntList l);
}
public static class P extends BasicAngle {
@ -719,11 +635,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(double angle, int i) {
return "u1(" + Math.toRadians(angle) + ") q[" + i + "];";
}
@Override
public String qiskitLine(double angle, IntList l) {
return "qc.u1(" + Math.toRadians(angle) + ", " + pythonArray(l) + ")";
}
}
public static class RX extends BasicAngle {
@ -763,11 +674,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(double angle, int i) {
return "rx(" + Math.toRadians(angle) + ") q[" + i + "];";
}
@Override
public String qiskitLine(double angle, IntList l) {
return "qc.rx(" + Math.toRadians(angle) + ", " + pythonArray(l) + ")";
}
}
public static class RY extends BasicAngle {
@ -807,11 +713,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(double angle, int i) {
return "ry(" + Math.toRadians(angle) + ") q[" + i + "];";
}
@Override
public String qiskitLine(double angle, IntList l) {
return "qc.ry(" + Math.toRadians(angle) + ", " + pythonArray(l) + ")";
}
}
public static class RZ extends BasicAngle {
@ -851,11 +752,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String qasmLine(double angle, int i) {
return "rz(" + Math.toRadians(angle) + ") q[" + i + "];";
}
@Override
public String qiskitLine(double angle, IntList l) {
return "qc.rz(" + Math.toRadians(angle) + ", " + pythonArray(l) + ")";
}
}
public static abstract class Control extends Basic {
@ -900,12 +796,12 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
if (c.isEmpty()) {
return withoutControl().getCode(type);
return withoutControl().qasmCode();
}
else if (c.size() == 1) {
return singleControlCode(type);
return singleControlQasmCode();
}
List<QuantumGate> decomposition = new ArrayList<>();
@ -913,7 +809,7 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
List<String> out = new ArrayList<>();
for (QuantumGate gate : decomposition) {
out.addAll(gate.getCode(type));
out.addAll(gate.qasmCode());
}
return out;
@ -924,33 +820,17 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
return ";";
}
@Override
public final String qiskitLine(IntList l) {
return "";
}
public List<String> singleControlCode(int type) {
public List<String> singleControlQasmCode() {
int c = list(this.c).getInt(0);
IntList l = list(n);
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < l.size(); i++) {
out.add(singleControlQasmLine(c, l.getInt(i)));
}
for (int i = 0; i < l.size(); i++) {
out.add(singleControlQasmLine(c, l.getInt(i)));
}
else if (type == 1) {
if (!l.isEmpty()) {
out.add(singleControlQiskitLine(c, l));
}
}
return out;
}
public abstract String singleControlQasmLine(int c, int i);
public abstract String singleControlQiskitLine(int c, IntList l);
}
public static class CX extends Control {
@ -1075,18 +955,18 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
if (c.isEmpty()) {
return withoutControl().getCode(type);
return withoutControl().qasmCode();
}
int c_size = c.size();
if (c_size == 1) {
return singleControlCode(type);
return singleControlQasmCode();
}
else if (c_size == 2) {
return doubleControlCode(type);
return doubleControlQasmCode();
}
List<String> out = new ArrayList<>();
@ -1094,7 +974,7 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
addRequiredDecomposition(decomposition);
for (QuantumGate gate : decomposition) {
out.addAll(gate.getCode(type));
out.addAll(gate.qasmCode());
}
return out;
}
@ -1104,38 +984,20 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
return "cx q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cx(" + c + ", " + pythonArray(l) + ")";
}
public List<String> doubleControlCode(int type) {
public List<String> doubleControlQasmCode() {
IntList c_list = list(c);
int c1 = c_list.getInt(0), c2 = c_list.getInt(1);
IntList l = list(n);
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < l.size(); i++) {
out.add(doubleControlQasmLine(c1, c2, l.getInt(i)));
}
for (int i = 0; i < l.size(); i++) {
out.add(doubleControlQasmLine(c1, c2, l.getInt(i)));
}
else if (type == 1) {
if (!l.isEmpty()) {
out.add(doubleControlQiskitLine(c1, c2, l));
}
}
return out;
}
public String doubleControlQasmLine(int c1, int c2, int i) {
return "ccx q[" + c1 + "], q[" + c2 + "], q[" + i + "];";
}
public String doubleControlQiskitLine(int c1, int c2, IntList l) {
return "qc.ccx(" + c1 + ", " + c2 + ", " + pythonArray(l) + ")";
}
}
public static class CY extends Control {
@ -1180,11 +1042,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "cy q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cy(" + c + ", " + pythonArray(l) + ")";
}
}
public static class CZ extends Control {
@ -1229,11 +1086,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "cz q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cz(" + c + ", " + pythonArray(l) + ")";
}
}
public static class CH extends Control {
@ -1278,11 +1130,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "ch q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.ch(" + c + ", " + pythonArray(l) + ")";
}
}
public static class CS extends Control {
@ -1327,11 +1174,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "cu1(pi/2) q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cu1(pi/2, " + c + ", " + pythonArray(l) + ")";
}
}
public static class CSdg extends Control {
@ -1376,11 +1218,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "cu1(-pi/2) q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cu1(-pi/2, " + c + ", " + pythonArray(l) + ")";
}
}
public static class CT extends Control {
@ -1425,11 +1262,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "cu1(pi/4) q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cu1(pi/4, " + c + ", " + pythonArray(l) + ")";
}
}
public static class CTdg extends Control {
@ -1474,11 +1306,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(int c, int i) {
return "cu1(-pi/4) q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(int c, IntList l) {
return "qc.cu1(-pi/4, " + c + ", " + pythonArray(l) + ")";
}
}
public static abstract class ControlAngle extends BasicAngle {
@ -1527,12 +1354,12 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
if (c.isEmpty()) {
return withoutControl().getCode(type);
return withoutControl().qasmCode();
}
else if (c.size() == 1) {
return singleControlCode(type);
return singleControlQasmCode();
}
List<QuantumGate> decomposition = new ArrayList<>();
@ -1540,7 +1367,7 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
List<String> out = new ArrayList<>();
for (QuantumGate gate : decomposition) {
out.addAll(gate.getCode(type));
out.addAll(gate.qasmCode());
}
return out;
@ -1551,33 +1378,17 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
return ";";
}
@Override
public final String qiskitLine(double angle, IntList l) {
return "";
}
public List<String> singleControlCode(int type) {
public List<String> singleControlQasmCode() {
int c = list(this.c).getInt(0);
IntList l = list(n);
List<String> out = new ArrayList<>();
if (type == 0) {
for (int i = 0; i < l.size(); i++) {
out.add(singleControlQasmLine(angle, c, l.getInt(i)));
}
for (int i = 0; i < l.size(); i++) {
out.add(singleControlQasmLine(angle, c, l.getInt(i)));
}
else if (type == 1) {
if (!l.isEmpty()) {
out.add(singleControlQiskitLine(angle, c, l));
}
}
return out;
}
public abstract String singleControlQasmLine(double angle, int c, int i);
public abstract String singleControlQiskitLine(double angle, int c, IntList l);
}
public static class CP extends ControlAngle {
@ -1622,11 +1433,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(double angle, int c, int i) {
return "cu1(" + Math.toRadians(angle) + ") q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(double angle, int c, IntList l) {
return "qc.cu1(" + Math.toRadians(angle) + ", " + c + ", " + pythonArray(l) + ")";
}
}
public static class CRX extends ControlAngle {
@ -1671,11 +1477,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(double angle, int c, int i) {
return "crx(" + Math.toRadians(angle) + ") q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(double angle, int c, IntList l) {
return "qc.crx(" + Math.toRadians(angle) + ", " + c + ", " + pythonArray(l) + ")";
}
}
public static class CRY extends ControlAngle {
@ -1720,11 +1521,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(double angle, int c, int i) {
return "cry(" + Math.toRadians(angle) + ") q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(double angle, int c, IntList l) {
return "qc.cry(" + Math.toRadians(angle) + ", " + c + ", " + pythonArray(l) + ")";
}
}
public static class CRZ extends ControlAngle {
@ -1769,11 +1565,6 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public String singleControlQasmLine(double angle, int c, int i) {
return "crz(" + Math.toRadians(angle) + ") q[" + c + "], q[" + i + "];";
}
@Override
public String singleControlQiskitLine(double angle, int c, IntList l) {
return "qc.crz(" + Math.toRadians(angle) + ", " + c + ", " + pythonArray(l) + ")";
}
}
public static class Swap extends QuantumGate<Swap> {
@ -1835,22 +1626,13 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
}
@Override
public List<String> getCode(int type) {
public List<String> qasmCode() {
List<String> out = new ArrayList<>();
if (i.size() == j.size()) {
if (type == 0) {
for (int k = 0; k < i.size(); k++) {
out.add("swap q[" + i.getInt(k) + "], q[" + j.getInt(k) + "];");
}
}
else if (type == 1) {
for (int k = 0; k < i.size(); k++) {
out.add("qc.swap(" + i.getInt(k) + ", " + j.getInt(k) + ")");
}
for (int k = 0; k < i.size(); k++) {
out.add("swap q[" + i.getInt(k) + "], q[" + j.getInt(k) + "];");
}
}
return out;
}
}
@ -1903,49 +1685,29 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
@Override
// TODO
public List<String> getCode(int type) {
public List<String> qasmCode() {
if (c.isEmpty()) {
return super.getCode(type);
return super.qasmCode();
}
List<String> out = new ArrayList<>();
if (i.size() == j.size() && !i.isEmpty()) {
if (i.size() == j.size()) {
IntList l = list(c);
if (type == 0) {
if (l.size() == 1) {
String s = "cswap q[" + l.getInt(0) + "], ";
for (int k = 0; k < i.size(); k++) {
out.add(s + "q[" + i.getInt(k) + "], q[" + j.getInt(k) + "];");
}
}
else {
out.add("// multi-controlled swap decomposition not yet implemented!");
String s = Strings.repeat("c", l.size()) + "swap ";
for (int k = 0; k < l.size(); k++) {
s += ("q[" + l.getInt(k) + "], ");
}
for (int k = 0; k < i.size(); k++) {
out.add(s + "q[" + i.getInt(k) + "], q[" + j.getInt(k) + "];");
}
if (l.size() == 1) {
String s = "cswap q[" + l.getInt(0) + "], ";
for (int k = 0; k < i.size(); k++) {
out.add(s + "q[" + i.getInt(k) + "], q[" + j.getInt(k) + "];");
}
}
else if (type == 1) {
if (l.size() == 1) {
String s = "qc.cswap(" + l.getInt(0) + ", ";
for (int k = 0; k < i.size(); k++) {
out.add(s + i.getInt(k) + ", " + j.getInt(k) + ")");
}
else {
out.add("// multi-controlled swap decomposition not yet implemented!");
String s = "// " + Strings.repeat('c', l.size()) + "swap ";
for (int k = 0; k < l.size(); k++) {
s += "q[" + l.getInt(k) + "], ";
}
else {
out.add("# multi-controlled swap decomposition not yet implemented!");
String s = "qc." + Strings.repeat("c", l.size()) + "swap(";
for (int k = 0; k < l.size(); k++) {
s += (l.getInt(k) + ", ");
}
for (int k = 0; k < i.size(); k++) {
out.add(s + i.getInt(k) + ", " + j.getInt(k) + ")");
}
for (int k = 0; k < i.size(); k++) {
out.add(s + "q[" + i.getInt(k) + "], q[" + j.getInt(k) + "];");
}
}
}
@ -2162,20 +1924,4 @@ public abstract class QuantumGate<GATE extends QuantumGate> {
public static boolean full(double angle) {
return angle % 720D == 0D;
}
public static String pythonArray(IntList list) {
return pythonArray(list, false);
}
public static String pythonArray(IntList list, boolean forceBrackets) {
if (!forceBrackets && list.size() == 1) {
return Integer.toString(list.getInt(0));
}
String out = "[";
for (int i : list) {
out += (i + ", ");
}
return StringHelper.removeSuffix(out, 2) + "]";
}
}

View File

@ -1,106 +0,0 @@
package nc.multiblock.qComputer.block;
import nc.enumm.IBlockMetaEnum;
import nc.multiblock.qComputer.tile.TileQuantumComputerCodeGenerator;
import net.minecraft.block.properties.*;
import net.minecraft.block.state.*;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockQuantumComputerCodeGenerator extends BlockQuantumComputerMetaPart<BlockQuantumComputerCodeGenerator.Type> {
public final static PropertyEnum<Type> TYPE = PropertyEnum.create("type", Type.class);
public BlockQuantumComputerCodeGenerator() {
super(Type.class, TYPE);
}
@Override
protected BlockStateContainer createBlockState() {
return new BlockStateContainer(this, new IProperty[] {TYPE});
}
@Override
public TileEntity createNewTileEntity(World worldIn, int meta) {
return values[meta].getTile();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (player == null) {
return false;
}
if (hand != EnumHand.MAIN_HAND || player.isSneaking()) {
return false;
}
return rightClickOnPart(world, pos, player, hand, facing);
}
public static enum Type implements IStringSerializable, IBlockMetaEnum {
QASM("qasm", 0),
QISKIT("qiskit", 1);
private final String name;
private final int id;
private Type(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
@Override
public int getID() {
return id;
}
@Override
public int getHarvestLevel() {
return 0;
}
@Override
public String getHarvestTool() {
return "pickaxe";
}
@Override
public float getHardness() {
return 2F;
}
@Override
public float getResistance() {
return 15F;
}
@Override
public int getLightValue() {
return 0;
}
public TileEntity getTile() {
switch (this) {
case QASM:
return new TileQuantumComputerCodeGenerator.Qasm();
case QISKIT:
return new TileQuantumComputerCodeGenerator.Qiskit();
default:
return null;
}
}
}
}

View File

@ -21,6 +21,11 @@ public class BlockQuantumComputerController extends BlockQuantumComputerPart {
return new TileQuantumComputerController();
}
@Override
public void onBlockAdded(World world, BlockPos pos, IBlockState state) {
super.onBlockAdded(world, pos, state);
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (player == null) {

View File

@ -34,8 +34,8 @@ public abstract class BlockQuantumComputerGate<T extends Enum<T> & IStringSerial
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
return QuantumGateEnums.SingleType.values()[meta].getTile();
public TileEntity createNewTileEntity(World world, int metadata) {
return QuantumGateEnums.SingleType.values()[metadata].getTile();
}
}
@ -53,8 +53,8 @@ public abstract class BlockQuantumComputerGate<T extends Enum<T> & IStringSerial
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
return QuantumGateEnums.ControlType.values()[meta].getTile();
public TileEntity createNewTileEntity(World world, int metadata) {
return QuantumGateEnums.ControlType.values()[metadata].getTile();
}
}
@ -72,8 +72,8 @@ public abstract class BlockQuantumComputerGate<T extends Enum<T> & IStringSerial
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
return QuantumGateEnums.SwapType.values()[meta].getTile();
public TileEntity createNewTileEntity(World world, int metadata) {
return QuantumGateEnums.SwapType.values()[metadata].getTile();
}
}

View File

@ -1,76 +0,0 @@
package nc.multiblock.qComputer.tile;
import static nc.config.NCConfig.quantum_max_qubits_code;
import nc.multiblock.qComputer.QuantumComputer;
import nc.util.Lang;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
public abstract class TileQuantumComputerCodeGenerator extends TileQuantumComputerPart {
protected final int codeType;
protected TileQuantumComputerCodeGenerator(int codeType) {
super();
this.codeType = codeType;
}
public static class Qasm extends TileQuantumComputerCodeGenerator {
public Qasm() {
super(0);
}
@Override
protected String getUnlocalizedCodeStartMessage() {
return "info.nuclearcraft.multitool.quantum_computer.controller.code_qasm_start";
}
}
public static class Qiskit extends TileQuantumComputerCodeGenerator {
public Qiskit() {
super(1);
}
@Override
protected String getUnlocalizedCodeStartMessage() {
return "info.nuclearcraft.multitool.quantum_computer.controller.code_qiskit_start";
}
}
@Override
public void onMachineAssembled(QuantumComputer multiblock) {
doStandardNullControllerResponse(multiblock);
}
@Override
public void onMachineBroken() {}
@Override
public boolean onUseMultitool(ItemStack multitoolStack, EntityPlayer player, World world, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (!player.isSneaking()) {
QuantumComputer qc = getMultiblock();
if (qc != null && qc.isAssembled()) {
if (qc.codeType >= 0) {
qc.printCode(player);
}
else if (qc.qubitCount() <= quantum_max_qubits_code) {
qc.codeStart = codeType;
player.sendMessage(new TextComponentString(Lang.localise(getUnlocalizedCodeStartMessage())));
}
else {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.code_too_many_qubits")));
}
return true;
}
}
return super.onUseMultitool(multitoolStack, player, world, facing, hitX, hitY, hitZ);
}
protected abstract String getUnlocalizedCodeStartMessage();
}

View File

@ -1,9 +1,14 @@
package nc.multiblock.qComputer.tile;
import nc.config.NCConfig;
import nc.multiblock.qComputer.*;
import nc.util.Lang;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ITickable;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
public class TileQuantumComputerController extends TileQuantumComputerPart implements ITickable {
@ -44,6 +49,27 @@ public class TileQuantumComputerController extends TileQuantumComputerPart imple
}
}
@Override
public boolean onUseMultitool(ItemStack multitoolStack, EntityPlayer player, World world, EnumFacing facing, float hitX, float hitY, float hitZ) {
if (player.isSneaking()) {
QuantumComputer qc = getMultiblock();
if (qc != null) {
if (qc.qasmWrite) {
qc.qasmPrint(player);
}
else if (qc.qubitCount() <= NCConfig.quantum_max_qubits_qasm) {
qc.qasmStart = true;
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.qasm_start")));
}
else {
player.sendMessage(new TextComponentString(Lang.localise("info.nuclearcraft.multitool.quantum_computer.controller.qasm_too_many_qubits")));
}
return true;
}
}
return super.onUseMultitool(multitoolStack, player, world, facing, hitX, hitY, hitZ);
}
@Override
public NBTTagCompound writeAll(NBTTagCompound nbt) {
super.writeAll(nbt);

View File

@ -26,7 +26,6 @@ public abstract class AbstractRecipeHandler<RECIPE extends IRecipe> {
protected @Nonnull List<RECIPE> recipeList = new ArrayList<>();
protected @Nonnull Long2ObjectMap<RECIPE> recipeCache = new Long2ObjectOpenHashMap<>();
protected long cacheSalt = 0L;
private static List<Class<?>> validItemInputs = Lists.newArrayList(IItemIngredient.class, ArrayList.class, String.class, Item.class, Block.class, ItemStack.class, ItemStack[].class);
private static List<Class<?>> validFluidInputs = Lists.newArrayList(IFluidIngredient.class, ArrayList.class, String.class, Fluid.class, FluidStack.class, FluidStack[].class);
@ -53,7 +52,7 @@ public abstract class AbstractRecipeHandler<RECIPE extends IRecipe> {
public abstract void addRecipe(Object... objects);
public @Nullable RecipeInfo<RECIPE> getRecipeInfoFromInputs(List<ItemStack> itemInputs, List<Tank> fluidInputs) {
RECIPE recipe = recipeCache.get(RecipeHelper.hashMaterialsRaw(itemInputs, fluidInputs, cacheSalt));
RECIPE recipe = recipeCache.get(RecipeHelper.hashMaterialsRaw(itemInputs, fluidInputs));
if (recipe != null) {
RecipeMatchResult matchResult = recipe.matchInputs(itemInputs, fluidInputs);
if (matchResult.matches()) {
@ -95,14 +94,8 @@ public abstract class AbstractRecipeHandler<RECIPE extends IRecipe> {
}
public void refreshCache() {
cacheSalt = 0L;
do {
recipeCache.clear();
}
while (!fillHashCache());
}
public boolean fillHashCache() {
recipeCache.clear();
recipeLoop: for (RECIPE recipe : recipeList) {
List<List<ItemStack>> itemInputLists = new ArrayList<>();
List<List<FluidStack>> fluidInputLists = new ArrayList<>();
@ -141,36 +134,26 @@ public abstract class AbstractRecipeHandler<RECIPE extends IRecipe> {
for (Pair<List<ItemStack>, List<FluidStack>> materials : materialListTuples) {
for (List<ItemStack> items : PermutationHelper.permutations(materials.getLeft())) {
for (List<FluidStack> fluids : PermutationHelper.permutations(materials.getRight())) {
long hash = RecipeHelper.hashMaterials(items, fluids, cacheSalt);
if (recipeCache.containsKey(hash)) {
cacheSalt++;
NCUtil.getLogger().info(getRecipeName() + " encountered a hash clash [" + RecipeHelper.getRecipeString(recipe) + " == " + RecipeHelper.getRecipeString(recipeCache.get(hash)) + "]! Incrementing salt to " + cacheSalt + " and restarting caching...");
return false;
}
else {
recipeCache.put(RecipeHelper.hashMaterials(items, fluids, cacheSalt), recipe);
}
recipeCache.put(RecipeHelper.hashMaterials(items, fluids), recipe);
}
}
}
}
return true;
}
public static void addValidItemInput(Class<?> itemInputType) {
public static void addValidItemInput(Class itemInputType) {
validItemInputs.add(itemInputType);
}
public static void addValidFluidInput(Class<?> fluidInputType) {
public static void addValidFluidInput(Class fluidInputType) {
validFluidInputs.add(fluidInputType);
}
public static void addValidItemOutput(Class<?> itemOutputType) {
public static void addValidItemOutput(Class itemOutputType) {
validItemOutputs.add(itemOutputType);
}
public static void addValidFluidOutput(Class<?> fluidOutputType) {
public static void addValidFluidOutput(Class fluidOutputType) {
validFluidOutputs.add(fluidOutputType);
}

View File

@ -509,32 +509,32 @@ public class RecipeHelper {
return new OreIngredient(oreName, stackSize);
}
public static long hashMaterialsRaw(List<ItemStack> items, List<Tank> fluids, long salt) {
public static long hashMaterialsRaw(List<ItemStack> items, List<Tank> fluids) {
long hash = 1L;
Iterator<ItemStack> itemIter = items.iterator();
while (itemIter.hasNext()) {
ItemStack stack = itemIter.next();
hash = 31L * hash + (stack == null || stack.isEmpty() ? 0L : RecipeItemHelper.pack(stack)) + salt;
hash = 31L * hash + (stack == null || stack.isEmpty() ? 0L : RecipeItemHelper.pack(stack));
}
Iterator<Tank> fluidIter = fluids.iterator();
while (fluidIter.hasNext()) {
Tank tank = fluidIter.next();
hash = 31L * hash + (tank == null || tank.getFluid() == null ? 0L : tank.getFluid().getFluid().getName().hashCode()) + salt;
hash = 31L * hash + (tank == null || tank.getFluid() == null ? 0L : tank.getFluid().getFluid().getName().hashCode());
}
return hash;
}
public static long hashMaterials(List<ItemStack> items, List<FluidStack> fluids, long salt) {
public static long hashMaterials(List<ItemStack> items, List<FluidStack> fluids) {
long hash = 1L;
Iterator<ItemStack> itemIter = items.iterator();
while (itemIter.hasNext()) {
ItemStack stack = itemIter.next();
hash = 31L * hash + (stack == null || stack.isEmpty() ? 0L : RecipeItemHelper.pack(stack)) + salt;
hash = 31L * hash + (stack == null || stack.isEmpty() ? 0L : RecipeItemHelper.pack(stack));
}
Iterator<FluidStack> fluidIter = fluids.iterator();
while (fluidIter.hasNext()) {
FluidStack stack = fluidIter.next();
hash = 31L * hash + (stack == null ? 0L : stack.getFluid().getName().hashCode()) + salt;
hash = 31L * hash + (stack == null ? 0L : stack.getFluid().getName().hashCode());
}
return hash;
}

View File

@ -443,46 +443,42 @@ public class CraftingRecipeHandler {
addShapedOreRecipe(NCBlocks.quantum_computer_controller, new Object[] {"EPE", "PFP", "EPE", 'E', "ingotExtreme", 'P', Items.ENDER_PEARL, 'F', "steelFrame"});
addShapedOreRecipe(NCBlocks.quantum_computer_qubit, new Object[] {"ESE", "PRP", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL, 'R', "blockRedstone"});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 0), new Object[] {"SES", "EPE", "SES", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 1), new Object[] {"SES", "EPE", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 2), new Object[] {"SSS", "EPE", "SSS", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 3), new Object[] {"SES", "SPS", "SES", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 4), new Object[] {"ESS", "EPE", "SSE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 6), new Object[] {"SSS", "EPE", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 8), new Object[] {"SSS", "SPS", "SEE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 0), new Object[] {"SES", "ECE", "SES", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 1), new Object[] {"SES", "ECE", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 2), new Object[] {"SSS", "ECE", "SSS", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 3), new Object[] {"SES", "SCS", "SES", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 4), new Object[] {"ESS", "ECE", "SSE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 6), new Object[] {"SSS", "ECE", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 8), new Object[] {"SSS", "SCS", "SEE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 5), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 4)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 4), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 5)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 7), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 6)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 6), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 7)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 0), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 9), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 1), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 10), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 2), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 11), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 4), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 5), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 5), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 4), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 6), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 7), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 7), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 6), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 9), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 0), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 10), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 1), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 11), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 2), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 9), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 0), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 10), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 1), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 11), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 2), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 0), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 9), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 1), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 10), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 2), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 11), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 4), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 5), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 5), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 4), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 6), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 7), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 7), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 6), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 9), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 0), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 10), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 1), "dustRedstone"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 11), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, 2), "dustRedstone"});
for (int i = 0; i < QuantumGateEnums.SingleType.values().length; i++) {
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, i), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, i), "dustEnergetic"});
}
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 4), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 5)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 6), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 7)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 9), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 0), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 10), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 1), Blocks.REDSTONE_TORCH});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 11), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, 2), Blocks.REDSTONE_TORCH});
for (int i : new int[] {0, 1, 2, 3, 4, 6, 8, 9, 10, 11}) {
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_single, 1, i), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_control, 1, i)});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_control, 1, i), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_single, 1, i)});
}
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_swap, 1, 0), new Object[] {"EES", "EPE", "SEE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_swap, 1, 1), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_swap, 1, 0), "dustEnergetic"});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_gate_swap, 1, 0), new Object[] {new ItemStack(NCBlocks.quantum_computer_gate_swap, 1, 1)});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_connector, 8), new Object[] {"ESE", "SPS", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL});
addShapedOreRecipe(new ItemStack(NCBlocks.quantum_computer_code_generator, 1, 0), new Object[] {"ESE", "PBP", "ESE", 'E', "ingotExtreme", 'S', "ingotSteel", 'P', Items.ENDER_PEARL, 'B', Items.WRITABLE_BOOK});
addShapelessOreRecipe(new ItemStack(NCBlocks.quantum_computer_code_generator, 1, 1), new Object[] {new ItemStack(NCBlocks.quantum_computer_code_generator, 1, 0)});
}
}

View File

@ -1,20 +0,0 @@
{
"forge_marker": 1,
"defaults": {
"model":"cube_all"
},
"variants": {
"type": {
"qasm": {
"textures": {
"all":"nuclearcraft:blocks/quantum_computer/code_generator/qasm"
}
},
"qiskit": {
"textures": {
"all":"nuclearcraft:blocks/quantum_computer/code_generator/qiskit"
}
}
}
}
}

View File

@ -424,14 +424,9 @@ tile.nuclearcraft.quantum_computer_gate_swap.cswap.name=Quantum Computer Control
tile.nuclearcraft.quantum_computer_gate_swap.cswap.desc=Performs a controlled swap on two lists of qubits.
tile.nuclearcraft.quantum_computer_connector.name=Quantum Computer Connector
tile.nuclearcraft.quantum_computer_port.name=Quantum Computer OC Port (WIP)
tile.nuclearcraft.quantum_computer_port.name=Quantum Computer Port (WIP)
tile.nuclearcraft.quantum_computer_port.desc=Used to access the quantum computer via OpenComputers.
tile.nuclearcraft.quantum_computer_code_generator.qasm.name=Quantum Computer QASM Code Generator
tile.nuclearcraft.quantum_computer_code_generator.qasm.desc=Used to generate QASM code for use with IBM Q.
tile.nuclearcraft.quantum_computer_code_generator.qiskit.name=Quantum Computer Qiskit Code Generator
tile.nuclearcraft.quantum_computer_code_generator.qiskit.desc=Used to generate Qiskit code for use with IBM Q.
tile.nuclearcraft.fluid_oxygen.name=Oxygen
fluid.oxygen=Oxygen
@ -2178,18 +2173,12 @@ info.nuclearcraft.multitool.quantum_computer.finish_second_swap_list=Gate now se
info.nuclearcraft.multitool.quantum_computer.control_swap_gate_info=Gate currently swapping qubits %s with qubits %s, controlled by qubits %s
info.nuclearcraft.multitool.quantum_computer.controller.code_qasm_start=Quantum Computer entering QASM mode! Gate operations will be recorded but not carried out in the game.
info.nuclearcraft.multitool.quantum_computer.controller.code_qiskit_start=Quantum Computer entering Qiskit mode! Gate operations will be recorded but not carried out in the game.
info.nuclearcraft.multitool.quantum_computer.controller.code_too_many_qubits=Quantum Computer can not enter code generation mode, too many qubits installed.
info.nuclearcraft.multitool.quantum_computer.controller.code_exit_too_many_qubits=Quantum Computer exiting code generation mode, too many qubits installed.
info.nuclearcraft.multitool.quantum_computer.controller.code_exit_empty=Quantum Computer exiting code generation mode.
info.nuclearcraft.multitool.quantum_computer.controller.qasm_start=Quantum Computer entering QASM mode! Gate operations will be recorded but not carried out in the game.
info.nuclearcraft.multitool.quantum_computer.controller.qasm_too_many_qubits=Quantum Computer can not enter QASM mode, too many qubits installed.
info.nuclearcraft.multitool.quantum_computer.controller.qasm_print=Quantum Computer exiting QASM mode, saved generated code to %s
info.nuclearcraft.multitool.quantum_computer.controller.qasm_error=Quantum Computer exiting QASM mode, an error occurred attempting save generated code to %s
info.nuclearcraft.multitool.quantum_computer.controller.qasm_exit_empty=Quantum Computer exiting QASM mode.
info.nuclearcraft.multitool.quantum_computer.controller.qiskit_print=Quantum Computer exiting Qiskit mode, saved generated code to %s
info.nuclearcraft.multitool.quantum_computer.controller.qiskit_error=Quantum Computer exiting Qiskit mode, an error occurred attempting save generated code to %s
info.nuclearcraft.multitool.quantum_computer.controller.qiskit_exit_empty=Quantum Computer exiting Qiskit mode.
info.nuclearcraft.multitool.quantum_computer.controller.qasm_exit_too_many_qubits=Quantum Computer exiting QASM mode, too many qubits installed to generate code.
info.nuclearcraft.multitool.quantum_computer.controller.qasm_exit=Quantum Computer exiting QASM mode.
item.nuclearcraft.geiger_counter.name=Geiger Counter
item.nuclearcraft.geiger_counter.desc=Detects radiation and informs the player of their rad count. Can be used to read the irradiation of entities. Will be muted if off the hotbar.
@ -2670,8 +2659,8 @@ gui.nc.config.category.quantum.tooltip=Configure quantum mechanical systems.
gui.nc.config.quantum_max_qubits_live=Max Live Qubits
gui.nc.config.quantum_max_qubits_live.comment=The maximum number of actively calculating qubits a single quantum computer multiblock can have. !!!WARNING!!! Allowing for complex circuits of more than seven qubits will begin to seriously impact performance and use up a huge amount of memory. Increase this limit with EXTREME caution!
gui.nc.config.quantum_max_qubits_code=Max Coding Qubits
gui.nc.config.quantum_max_qubits_code.comment=The maximum number of qubits a single quantum computer multiblock can have for generating code. !!!WARNING!!! Gates with more control qubits will take increasingly more work and memory to decompile into basic operations, thus will generate increasingly mode code. If generating QASM code, IBM Q Experience's circuit composer will begin to struggle to deal with more than a few hundred lines. Increase this limit with EXTREME caution!
gui.nc.config.quantum_max_qubits_qasm=Max QASM Qubits
gui.nc.config.quantum_max_qubits_qasm.comment=The maximum number of qubits a single quantum computer multiblock can have for generating QASM code. !!!WARNING!!! Gates with more control qubits will take increasingly more work and memory to decompile into basic operations, thus will generate increasingly mode code. IBMQ Experience's circuit composer will begin to struggle to deal with more than a few hundreds of lines of code. Increase this limit with EXTREME caution!
gui.nc.config.quantum_angle_precision=Gate Angle Precision
gui.nc.config.quantum_angle_precision.comment=Controls the precision allowed for setting the working angle of gates by defining the number of available angles, uniformly distributed from 0 to 360 degrees.
@ -3160,7 +3149,6 @@ nuclearcraft.multiblock_validation.turbine.different_type_blades=The rotor blade
nuclearcraft.multiblock_validation.turbine.missing_blades=Each section of the rotor shaft must have rotor blades or stators of the same type extend fully to the wall for the turbine to form
nuclearcraft.multiblock_validation.quantum_computer.too_many_qubits=There are %s qubits connected to this quantum computer; there can only be %s at most for it to form
nuclearcraft.multiblock_validation.quantum_computer.too_many_qubits=There must be no more than one code generator connected to this quantum computer
nuclearcraft.collector.jei_name=Collector
nuclearcraft.multiblock_gui.fission_moderator.jei_name=Fission Moderator

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 B

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 B

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 731 B

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 B

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 744 B

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 B

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 B

View File

@ -1,8 +1,7 @@
Add salt-based fix for recipe hash caching (start from zero, if there's a clash, start again after incrementing)
Test with iron + coal alloy furnace recipe in modified Enigmatica 2 instance
Suggestions from: This probably wont happen but in stead of multiblock reactors
Generate Qiskit code?
Adjacent MSR vessels with same filter form bundle to share flux, shared criticality factor is sum of single vessel criticality factors
Take number of available open faces of vessel bundle into account when calculating the heat multiplier (and efficiency)